Skip to content
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

Make new tables take new flags #112

Closed
wants to merge 1 commit into from

Conversation

mark-i-m
Copy link
Contributor

@mark-i-m mark-i-m commented Jan 1, 2020

When using RecursivePageTables::map_to(...), if new page tables are created, they do not use the page table flags of the new page. This means that e.g. if we map something as USER_ACCESSIBLE and we create a new page table, then counter-intuitively (and tediously), we have to up the page table hierarchy and figure out which entries should be made more permissive.

This PR means that instead when new page tables are created they get the same permissions as the new page, while old page table entries remain untouched.

This is a breaking change.

@phil-opp
Copy link
Member

phil-opp commented Jan 2, 2020

Thanks a lot for reporting this issue!

I'm not sure if inheriting the flags of the new page is the best solution, though. The problem I see is that adding a single mapping in for the same level 4 entry affects all following mappings to that entry. For example, you might break your code by reordering the map_to operations for a memory region if they use different flags. Thus, local reasoning about the effects of a mapping is not possible anymore.

I think a better solution would be to automatically add the required flags to parent page tables when creating a mapping. This would mean that when we map a page as user accessible, the map_to function would add the flag to the page tables of all levels, even if they already exist.

@phil-opp
Copy link
Member

phil-opp commented Jan 2, 2020

To implement this, we could OR the flags of existing tables with the flags of the page in the else block here:

@phil-opp
Copy link
Member

phil-opp commented Jan 2, 2020

Also, we would need to update the code for MappedPageTable too, in order to keep the behavior consistent between different implementations of the Mapper trait. The required changes should be very similar since we also have a create_next_table function for MappedPageTable.

@phil-opp
Copy link
Member

phil-opp commented Jan 2, 2020

Given that this changes the behavior of an existing function, this is a breaking change. I updated the description of this pull request to ensure that I don't forget about this when releasing a new version.

@mark-i-m
Copy link
Contributor Author

mark-i-m commented Jan 2, 2020

Thanks for the response! I agree with the issue you raised but I would point out that it is already true today: you can't reason locally because you need to know what had happened before (eg in my case, I need to know that I should enable all user-access bits up to the root somehow.

I think what we really want is some sort of Visitor and MutVisitor traits that allow traversing and/or modifying page table sets in different ways (eg pruning away unneeded tables, changing flags, adding new entries and tables, etc). That would solve a lot of problems, I think.

However, I don't think I have time to implement such a thing.

@phil-opp
Copy link
Member

phil-opp commented Jan 5, 2020

I think what we really want is some sort of Visitor and MutVisitor traits that allow traversing and/or modifying page table sets in different ways (eg pruning away unneeded tables, changing flags, adding new entries and tables, etc). That would solve a lot of problems, I think.

Interesting idea, but I don't have the time to experiment with something like this either.

I agree with the issue you raised but I would point out that it is already true today: you can't readon locally because you need to know what had happened before (eg in my case, I need to know that I should enable all user-access bits up to the root somehow.

Yes, but at least it does not matter which mapping is created first.


What do you think about my idea to automatically add the required flags mentioned above:

I think a better solution would be to automatically add the required flags to parent page tables when creating a mapping. This would mean that when we map a page as user accessible, the map_to function would add the flag to the page tables of all levels, even if they already exist.

?

With this approach we would automatically add the USER_ACCESSIBLE flag to all parent page tables when a mapping with that flag is created. This way, you would never need to set those flags on higher level tables manually.

@mark-i-m
Copy link
Contributor Author

With this approach we would automatically add the USER_ACCESSIBLE flag to all parent page tables when a mapping with that flag is created. This way, you would never need to set those flags on higher level tables manually.

I guess it could be a reasonable default for now, but I'm generally against changing the flags at any level without the user being aware... If we do this, we should make sure it is in the documentation.

Also, would we do this for only USER_ACCESSIBLE or also for other flags (e.g. GLOBAL, PRESENT, etc)?

@mark-i-m
Copy link
Contributor Author

Closing in favor of #114.

@mark-i-m mark-i-m closed this Jan 24, 2020
@mark-i-m mark-i-m mentioned this pull request Jan 24, 2020
@phil-opp
Copy link
Member

Also, would we do this for only USER_ACCESSIBLE or also for other flags (e.g. GLOBAL, PRESENT, etc)?

The idea was to do this for all flags that have the same behavior at a higher level table, such as PRESENT or WRITABLE.

I'm generally against changing the flags at any level without the user being aware... If we do this, we should make sure it is in the documentation.

I completely agree that this should be mentioned prominently in the documentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants