Changeset 1c7a170 in mainline for kernel/generic/include/mm/mm.h


Ignore:
Timestamp:
2018-03-27T16:49:29Z (7 years ago)
Author:
GitHub <noreply@…>
Parents:
f303afc6 (diff), 94d211e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-27 16:49:29)
git-committer:
GitHub <noreply@…> (2018-03-27 16:49:29)
Message:

Merge 94d211e1f212626c420cf42c22b056ac1db9c0f1 into f303afc69bfdfc798071487501f775a7c4d8c475

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/mm/mm.h

    rf303afc6 r1c7a170  
    3636#define KERN_MM_H_
    3737
    38 #define PAGE_CACHEABLE_SHIFT            0
    39 #define PAGE_NOT_CACHEABLE_SHIFT        PAGE_CACHEABLE_SHIFT
    40 #define PAGE_PRESENT_SHIFT              1
    41 #define PAGE_NOT_PRESENT_SHIFT          PAGE_PRESENT_SHIFT
    42 #define PAGE_USER_SHIFT                 2
    43 #define PAGE_KERNEL_SHIFT               PAGE_USER_SHIFT
     38#include <assert.h>
     39#include <stdbool.h>
     40
     41#define PAGE_NOT_CACHEABLE_SHIFT        0
     42#define PAGE_CACHEABLE_SHIFT            1
     43#define PAGE_NOT_PRESENT_SHIFT          2
    4444#define PAGE_READ_SHIFT                 3
    4545#define PAGE_WRITE_SHIFT                4
    4646#define PAGE_EXEC_SHIFT                 5
    4747#define PAGE_GLOBAL_SHIFT               6
     48#define PAGE_USER_SHIFT                 7
     49#define PAGE_KERNEL_SHIFT               8
    4850
    49 #define PAGE_NOT_CACHEABLE              (0 << PAGE_CACHEABLE_SHIFT)
     51/* Cacheability.
     52 * Platform-independent code should always use PAGE_CACHEABLE for normal memory,
     53 * and PAGE_NOT_CACHEABLE for I/O memory.
     54 * In particular, setting PAGE_NOT_CACHEABLE on normal memory does not prevent
     55 * caching on all platforms. You have been warned.
     56 * Exactly one must be present for leaf pages.
     57 * None may be present for non-leaf entries.
     58 */
     59
     60#define PAGE_NOT_CACHEABLE              (1 << PAGE_NOT_CACHEABLE_SHIFT)
    5061#define PAGE_CACHEABLE                  (1 << PAGE_CACHEABLE_SHIFT)
    5162
    52 #define PAGE_PRESENT                    (0 << PAGE_PRESENT_SHIFT)
    53 #define PAGE_NOT_PRESENT                (1 << PAGE_PRESENT_SHIFT)
    5463
    55 #define PAGE_USER                       (1 << PAGE_USER_SHIFT)
    56 #define PAGE_KERNEL                     (0 << PAGE_USER_SHIFT)
     64/* Discriminant, exactly one of the following seven must be set for
     65 * the flags to be valid. Furthermore, the first two are only legal
     66 * for setting individual page table entries. Setting an entry
     67 * to PAGE_NOT_PRESENT renders the entry eligible for removal.
     68 * In an earlier iteration of this interface, page could be not
     69 * present but valid, preventing removal. This has been changed, and
     70 * if future iterations allow kernel to hide data (e.g. swap identifiers)
     71 * in page tables, it should be achieved by adding a separate discriminant.
     72 */
     73#define PAGE_NOT_PRESENT          (1 << PAGE_NOT_PRESENT_SHIFT)
    5774
    58 #define PAGE_READ                       (1 << PAGE_READ_SHIFT)
    59 #define PAGE_WRITE                      (1 << PAGE_WRITE_SHIFT)
    60 #define PAGE_EXEC                       (1 << PAGE_EXEC_SHIFT)
     75// TODO: This will be a separate flag.
     76#define PAGE_NEXT_LEVEL_PT        (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC | PAGE_USER | PAGE_CACHEABLE)
    6177
    62 #define PAGE_GLOBAL                     (1 << PAGE_GLOBAL_SHIFT)
     78#define PAGE_READ_ONLY            (_PAGE_READ)
     79#define PAGE_READ_EXECUTE         (_PAGE_READ | _PAGE_EXEC)
     80#define PAGE_READ_WRITE           (_PAGE_READ | _PAGE_WRITE)
     81#define PAGE_READ_WRITE_EXECUTE   (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC)
     82#define PAGE_EXECUTE_ONLY         (_PAGE_EXEC)
     83
     84/* Individual permissions.
     85 * Only used when the flags are tested or translated from other
     86 * format. In constant flags, use one of the combinations above.
     87 */
     88#define _PAGE_READ                (1 << PAGE_READ_SHIFT)
     89#define _PAGE_WRITE               (1 << PAGE_WRITE_SHIFT)
     90#define _PAGE_EXEC                (1 << PAGE_EXEC_SHIFT)
     91
     92/* Global page. Can be combined with anything except PAGE_NOT_PRESENT.
     93 * PAGE_GLOBAL on non-leaf entry means all the leaf entries under it are global,
     94 * even if they don't have the PAGE_GLOBAL flag themselves.
     95 */
     96#define PAGE_GLOBAL               (1 << PAGE_GLOBAL_SHIFT)
     97
     98/* Protection.
     99 * PAGE_USER for memory accessible to userspace programs, PAGE_KERNEL for
     100 * memory accessible only to the kernel. Note that on some platforms,
     101 * PAGE_USER pages are accessible to kernel, while on others, they are not.
     102 * For non-leaf entries, PAGE_USER means that all of the lower-level pages
     103 * are PAGE_USER, likewise with PAGE_KERNEL. Exactly one of these two must be
     104 * used for leaf entries, but it may be omitted for non-leaf entries.
     105 */
     106#define PAGE_USER                 (1 << PAGE_USER_SHIFT)
     107#define PAGE_KERNEL               (1 << PAGE_KERNEL_SHIFT)
     108
     109
     110
     111static inline bool PAGE_FLAGS_VALID(unsigned flags) {
     112        // TODO
     113
     114        /* Empty entry supports no flags. */
     115        if (flags & PAGE_NOT_PRESENT)
     116                return flags == PAGE_NOT_PRESENT;
     117
     118        /* PAGE_USER and PAGE_KERNEL are mutually exclusive. */
     119        if ((flags & PAGE_USER) && (flags & PAGE_KERNEL))
     120                return false;
     121
     122        /* Check allowed flags for non-leaf entry. */
     123        if (flags & PAGE_NEXT_LEVEL_PT)
     124                return flags == (flags & (PAGE_NEXT_LEVEL_PT | PAGE_GLOBAL | PAGE_USER | PAGE_KERNEL));
     125
     126        /* Leaf entries only. */
     127
     128        /* Check that at least one permission is set. */
     129        if (!(flags & (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC)))
     130                return false;
     131
     132        /* Check that write implies read. */
     133        if ((flags & _PAGE_WRITE) && !(flags & _PAGE_READ))
     134                return false;
     135
     136        /* One of PAGE_USER and PAGE_KERNEL must be used. */
     137        if (!(flags & (PAGE_USER | PAGE_KERNEL)))
     138                return false;
     139
     140        /* One of PAGE_CACHEABLE and PAGE_NOT_CACHEABLE must be used. */
     141        if ((flags & PAGE_CACHEABLE) && (flags & PAGE_NOT_CACHEABLE))
     142                return false;
     143        if (!(flags & (PAGE_CACHEABLE | PAGE_NOT_CACHEABLE)))
     144                return false;
     145
     146        return true;
     147}
    63148
    64149#endif
Note: See TracChangeset for help on using the changeset viewer.