Rev 1821 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1821 | Rev 1824 | ||
---|---|---|---|
Line 41... | Line 41... | ||
41 | #define PAGE_SIZE FRAME_SIZE |
41 | #define PAGE_SIZE FRAME_SIZE |
42 | 42 | ||
43 | #ifdef KERNEL |
43 | #ifdef KERNEL |
44 | 44 | ||
45 | #ifndef __ASM__ |
45 | #ifndef __ASM__ |
46 | # include <arch/hypercall.h> |
- | |
47 | # define KA2PA(x) (((uintptr_t) (x)) - 0x80000000) |
46 | # define KA2PA(x) (((uintptr_t) (x)) - 0x80000000) |
48 | # define PA2KA(x) (((uintptr_t) (x)) + 0x80000000) |
47 | # define PA2KA(x) (((uintptr_t) (x)) + 0x80000000) |
49 | #else |
48 | #else |
50 | # define KA2PA(x) ((x) - 0x80000000) |
49 | # define KA2PA(x) ((x) - 0x80000000) |
51 | # define PA2KA(x) ((x) + 0x80000000) |
50 | # define PA2KA(x) ((x) + 0x80000000) |
Line 63... | Line 62... | ||
63 | #define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 22) & 0x3ff) |
62 | #define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 22) & 0x3ff) |
64 | #define PTL1_INDEX_ARCH(vaddr) 0 |
63 | #define PTL1_INDEX_ARCH(vaddr) 0 |
65 | #define PTL2_INDEX_ARCH(vaddr) 0 |
64 | #define PTL2_INDEX_ARCH(vaddr) 0 |
66 | #define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 12) & 0x3ff) |
65 | #define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 12) & 0x3ff) |
67 | 66 | ||
68 | #define GET_PTL1_ADDRESS_ARCH(ptl0, i) ((pte_t *)((((pte_t *)(ptl0))[(i)].frame_address) << 12)) |
67 | #define GET_PTL1_ADDRESS_ARCH(ptl0, i) ((pte_t *) MA2PA((((pte_t *) (ptl0))[(i)].frame_address) << 12)) |
69 | #define GET_PTL2_ADDRESS_ARCH(ptl1, i) (ptl1) |
68 | #define GET_PTL2_ADDRESS_ARCH(ptl1, i) (ptl1) |
70 | #define GET_PTL3_ADDRESS_ARCH(ptl2, i) (ptl2) |
69 | #define GET_PTL3_ADDRESS_ARCH(ptl2, i) (ptl2) |
71 | #define GET_FRAME_ADDRESS_ARCH(ptl3, i) ((uintptr_t)((((pte_t *)(ptl3))[(i)].frame_address) << 12)) |
70 | #define GET_FRAME_ADDRESS_ARCH(ptl3, i) ((uintptr_t) MA2PA((((pte_t *) (ptl3))[(i)].frame_address) << 12)) |
72 | 71 | ||
73 | #define SET_PTL0_ADDRESS_ARCH(ptl0) { \ |
72 | #define SET_PTL0_ADDRESS_ARCH(ptl0) { \ |
74 | mmuext_op_t mmu_ext; \ |
73 | mmuext_op_t mmu_ext; \ |
- | 74 | \ |
|
75 | mmu_ext.cmd = MMUEXT_NEW_BASEPTR; \ |
75 | mmu_ext.cmd = MMUEXT_NEW_BASEPTR; \ |
76 | mmu_ext.arg1.mfn = ADDR2PFN(PA2MA(ptl0)); \ |
76 | mmu_ext.mfn = ADDR2PFN(PA2MA(ptl0)); \ |
77 | xen_mmuext_op(&mmu_ext, 1, NULL, DOMID_SELF); \ |
77 | xen_mmuext_op(&mmu_ext, 1, NULL, DOMID_SELF); \ |
78 | } |
78 | } |
- | 79 | ||
79 | #define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) { \ |
80 | #define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) { \ |
80 | mmu_update_t update; \ |
81 | mmu_update_t update; \ |
- | 82 | \ |
|
81 | update.ptr = PA2MA(KA2PA(&((pte_t *) (ptl0))[(i)])); \ |
83 | update.ptr = PA2MA(KA2PA(&((pte_t *) (ptl0))[(i)])); \ |
82 | update.val = PA2MA(a); \ |
84 | update.val = PA2MA(a) | 0x0003; \ |
83 | xen_mmu_update(&update, 1, NULL, DOMID_SELF); \ |
85 | xen_mmu_update(&update, 1, NULL, DOMID_SELF); \ |
84 | } |
86 | } |
85 | #define SET_PTL2_ADDRESS_ARCH(ptl1, i, a) |
87 | #define SET_PTL2_ADDRESS_ARCH(ptl1, i, a) |
86 | #define SET_PTL3_ADDRESS_ARCH(ptl2, i, a) |
88 | #define SET_PTL3_ADDRESS_ARCH(ptl2, i, a) |
87 | #define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) { \ |
89 | #define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) (((pte_t *) (ptl3))[(i)].frame_address = PA2MA(a) >> 12) |
88 | mmu_update_t update; \ |
- | |
89 | update.ptr = PA2MA(KA2PA(&((pte_t *) (ptl3))[(i)])); \ |
- | |
90 | update.val = PA2MA(a); \ |
- | |
91 | xen_mmu_update(&update, 1, NULL, DOMID_SELF); \ |
- | |
92 | } |
- | |
93 | 90 | ||
94 | #define GET_PTL1_FLAGS_ARCH(ptl0, i) get_pt_flags((pte_t *)(ptl0), (index_t)(i)) |
91 | #define GET_PTL1_FLAGS_ARCH(ptl0, i) get_pt_flags((pte_t *) (ptl0), (index_t)(i)) |
95 | #define GET_PTL2_FLAGS_ARCH(ptl1, i) PAGE_PRESENT |
92 | #define GET_PTL2_FLAGS_ARCH(ptl1, i) PAGE_PRESENT |
96 | #define GET_PTL3_FLAGS_ARCH(ptl2, i) PAGE_PRESENT |
93 | #define GET_PTL3_FLAGS_ARCH(ptl2, i) PAGE_PRESENT |
97 | #define GET_FRAME_FLAGS_ARCH(ptl3, i) get_pt_flags((pte_t *)(ptl3), (index_t)(i)) |
94 | #define GET_FRAME_FLAGS_ARCH(ptl3, i) get_pt_flags((pte_t *) (ptl3), (index_t)(i)) |
98 | 95 | ||
99 | #define SET_PTL1_FLAGS_ARCH(ptl0, i, x) set_pt_flags((pte_t *)(ptl0), (index_t)(i), (x)) |
96 | #define SET_PTL1_FLAGS_ARCH(ptl0, i, x) set_pt_flags((pte_t *) (ptl0), (index_t)(i), (x)) |
100 | #define SET_PTL2_FLAGS_ARCH(ptl1, i, x) |
97 | #define SET_PTL2_FLAGS_ARCH(ptl1, i, x) |
101 | #define SET_PTL3_FLAGS_ARCH(ptl2, i, x) |
98 | #define SET_PTL3_FLAGS_ARCH(ptl2, i, x) |
102 | #define SET_FRAME_FLAGS_ARCH(ptl3, i, x) set_pt_flags((pte_t *)(ptl3), (index_t)(i), (x)) |
99 | #define SET_FRAME_FLAGS_ARCH(ptl3, i, x) set_pt_flags((pte_t *) (ptl3), (index_t)(i), (x)) |
103 | 100 | ||
104 | #define PTE_VALID_ARCH(p) (*((uint32_t *) (p)) != 0) |
101 | #define PTE_VALID_ARCH(p) (*((uint32_t *) (p)) != 0) |
105 | #define PTE_PRESENT_ARCH(p) ((p)->present != 0) |
102 | #define PTE_PRESENT_ARCH(p) ((p)->present != 0) |
106 | #define PTE_GET_FRAME_ARCH(p) ((p)->frame_address << FRAME_WIDTH) |
103 | #define PTE_GET_FRAME_ARCH(p) ((p)->frame_address << FRAME_WIDTH) |
107 | #define PTE_WRITABLE_ARCH(p) ((p)->writeable != 0) |
104 | #define PTE_WRITABLE_ARCH(p) ((p)->writeable != 0) |
Line 111... | Line 108... | ||
111 | 108 | ||
112 | #include <mm/page.h> |
109 | #include <mm/page.h> |
113 | #include <arch/types.h> |
110 | #include <arch/types.h> |
114 | #include <arch/mm/frame.h> |
111 | #include <arch/mm/frame.h> |
115 | #include <typedefs.h> |
112 | #include <typedefs.h> |
- | 113 | #include <arch/hypercall.h> |
|
116 | 114 | ||
117 | /* Page fault error codes. */ |
115 | /* Page fault error codes. */ |
118 | 116 | ||
119 | /** When bit on this position is 0, the page fault was caused by a not-present page. */ |
117 | /** When bit on this position is 0, the page fault was caused by a not-present page. */ |
120 | #define PFERR_CODE_P (1 << 0) |
118 | #define PFERR_CODE_P (1 << 0) |
Line 142... | Line 140... | ||
142 | unsigned soft_valid : 1; /**< Valid content even if the present bit is not set. */ |
140 | unsigned soft_valid : 1; /**< Valid content even if the present bit is not set. */ |
143 | unsigned avl : 2; |
141 | unsigned avl : 2; |
144 | unsigned frame_address : 20; |
142 | unsigned frame_address : 20; |
145 | } __attribute__ ((packed)); |
143 | } __attribute__ ((packed)); |
146 | 144 | ||
- | 145 | typedef struct { |
|
- | 146 | uint64_t ptr; /**< Machine address of PTE */ |
|
- | 147 | union { /**< New contents of PTE */ |
|
- | 148 | uint64_t val; |
|
- | 149 | pte_t pte; |
|
- | 150 | }; |
|
- | 151 | } mmu_update_t; |
|
- | 152 | ||
- | 153 | typedef struct { |
|
- | 154 | unsigned int cmd; |
|
- | 155 | union { |
|
- | 156 | unsigned long mfn; |
|
- | 157 | unsigned long linear_addr; |
|
- | 158 | }; |
|
- | 159 | union { |
|
- | 160 | unsigned int nr_ents; |
|
- | 161 | void *vcpumask; |
|
- | 162 | }; |
|
- | 163 | } mmuext_op_t; |
|
- | 164 | ||
- | 165 | static inline int xen_update_va_mapping(const void *va, const pte_t pte, const unsigned int flags) |
|
- | 166 | { |
|
- | 167 | return hypercall4(XEN_UPDATE_VA_MAPPING, va, pte, 0, flags); |
|
- | 168 | } |
|
- | 169 | ||
- | 170 | static inline int xen_mmu_update(const mmu_update_t *req, const unsigned int count, unsigned int *success_count, domid_t domid) |
|
- | 171 | { |
|
- | 172 | return hypercall4(XEN_MMU_UPDATE, req, count, success_count, domid); |
|
- | 173 | } |
|
- | 174 | ||
- | 175 | static inline int xen_mmuext_op(const mmuext_op_t *op, const unsigned int count, unsigned int *success_count, domid_t domid) |
|
- | 176 | { |
|
- | 177 | return hypercall4(XEN_MMUEXT_OP, op, count, success_count, domid); |
|
- | 178 | } |
|
- | 179 | ||
147 | static inline int get_pt_flags(pte_t *pt, index_t i) |
180 | static inline int get_pt_flags(pte_t *pt, index_t i) |
148 | { |
181 | { |
149 | pte_t *p = &pt[i]; |
182 | pte_t *p = &pt[i]; |
150 | 183 | ||
151 | return ( |
184 | return ( |