diff options
-rw-r--r-- | arch/x86/xen/enlighten.c | 13 | ||||
-rw-r--r-- | arch/x86/xen/mmu.c | 21 | ||||
-rw-r--r-- | arch/x86/xen/mmu.h | 4 | ||||
-rw-r--r-- | include/xen/interface/features.h | 3 | ||||
-rw-r--r-- | include/xen/interface/xen.h | 9 |
5 files changed, 45 insertions, 5 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 0b7553cbc529..bd74229081c3 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -168,7 +168,9 @@ static void __init xen_banner(void) | |||
168 | { | 168 | { |
169 | printk(KERN_INFO "Booting paravirtualized kernel on %s\n", | 169 | printk(KERN_INFO "Booting paravirtualized kernel on %s\n", |
170 | pv_info.name); | 170 | pv_info.name); |
171 | printk(KERN_INFO "Hypervisor signature: %s\n", xen_start_info->magic); | 171 | printk(KERN_INFO "Hypervisor signature: %s%s\n", |
172 | xen_start_info->magic, | ||
173 | xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : ""); | ||
172 | } | 174 | } |
173 | 175 | ||
174 | static void xen_cpuid(unsigned int *ax, unsigned int *bx, | 176 | static void xen_cpuid(unsigned int *ax, unsigned int *bx, |
@@ -1243,6 +1245,8 @@ asmlinkage void __init xen_start_kernel(void) | |||
1243 | 1245 | ||
1244 | BUG_ON(memcmp(xen_start_info->magic, "xen-3", 5) != 0); | 1246 | BUG_ON(memcmp(xen_start_info->magic, "xen-3", 5) != 0); |
1245 | 1247 | ||
1248 | xen_setup_features(); | ||
1249 | |||
1246 | /* Install Xen paravirt ops */ | 1250 | /* Install Xen paravirt ops */ |
1247 | pv_info = xen_info; | 1251 | pv_info = xen_info; |
1248 | pv_init_ops = xen_init_ops; | 1252 | pv_init_ops = xen_init_ops; |
@@ -1252,14 +1256,17 @@ asmlinkage void __init xen_start_kernel(void) | |||
1252 | pv_apic_ops = xen_apic_ops; | 1256 | pv_apic_ops = xen_apic_ops; |
1253 | pv_mmu_ops = xen_mmu_ops; | 1257 | pv_mmu_ops = xen_mmu_ops; |
1254 | 1258 | ||
1259 | if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) { | ||
1260 | pv_mmu_ops.ptep_modify_prot_start = xen_ptep_modify_prot_start; | ||
1261 | pv_mmu_ops.ptep_modify_prot_commit = xen_ptep_modify_prot_commit; | ||
1262 | } | ||
1263 | |||
1255 | machine_ops = xen_machine_ops; | 1264 | machine_ops = xen_machine_ops; |
1256 | 1265 | ||
1257 | #ifdef CONFIG_SMP | 1266 | #ifdef CONFIG_SMP |
1258 | smp_ops = xen_smp_ops; | 1267 | smp_ops = xen_smp_ops; |
1259 | #endif | 1268 | #endif |
1260 | 1269 | ||
1261 | xen_setup_features(); | ||
1262 | |||
1263 | /* Get mfn list */ | 1270 | /* Get mfn list */ |
1264 | if (!xen_feature(XENFEAT_auto_translated_physmap)) | 1271 | if (!xen_feature(XENFEAT_auto_translated_physmap)) |
1265 | xen_build_dynamic_phys_to_machine(); | 1272 | xen_build_dynamic_phys_to_machine(); |
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 8132aa8c5d49..846dad7d54a5 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -323,6 +323,27 @@ out: | |||
323 | preempt_enable(); | 323 | preempt_enable(); |
324 | } | 324 | } |
325 | 325 | ||
326 | pte_t xen_ptep_modify_prot_start(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | ||
327 | { | ||
328 | /* Just return the pte as-is. We preserve the bits on commit */ | ||
329 | return *ptep; | ||
330 | } | ||
331 | |||
332 | void xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr, | ||
333 | pte_t *ptep, pte_t pte) | ||
334 | { | ||
335 | struct multicall_space mcs; | ||
336 | struct mmu_update *u; | ||
337 | |||
338 | mcs = xen_mc_entry(sizeof(*u)); | ||
339 | u = mcs.args; | ||
340 | u->ptr = virt_to_machine(ptep).maddr | MMU_PT_UPDATE_PRESERVE_AD; | ||
341 | u->val = pte_val_ma(pte); | ||
342 | MULTI_mmu_update(mcs.mc, u, 1, NULL, DOMID_SELF); | ||
343 | |||
344 | xen_mc_issue(PARAVIRT_LAZY_MMU); | ||
345 | } | ||
346 | |||
326 | /* Assume pteval_t is equivalent to all the other *val_t types. */ | 347 | /* Assume pteval_t is equivalent to all the other *val_t types. */ |
327 | static pteval_t pte_mfn_to_pfn(pteval_t val) | 348 | static pteval_t pte_mfn_to_pfn(pteval_t val) |
328 | { | 349 | { |
diff --git a/arch/x86/xen/mmu.h b/arch/x86/xen/mmu.h index e3dd09e25c63..297bf9f5b8bc 100644 --- a/arch/x86/xen/mmu.h +++ b/arch/x86/xen/mmu.h | |||
@@ -52,4 +52,8 @@ void xen_set_pud_hyper(pud_t *ptr, pud_t val); | |||
52 | void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep); | 52 | void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep); |
53 | void xen_pmd_clear(pmd_t *pmdp); | 53 | void xen_pmd_clear(pmd_t *pmdp); |
54 | 54 | ||
55 | pte_t xen_ptep_modify_prot_start(struct mm_struct *mm, unsigned long addr, pte_t *ptep); | ||
56 | void xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr, | ||
57 | pte_t *ptep, pte_t pte); | ||
58 | |||
55 | #endif /* _XEN_MMU_H */ | 59 | #endif /* _XEN_MMU_H */ |
diff --git a/include/xen/interface/features.h b/include/xen/interface/features.h index d73228d16488..f51b6413b054 100644 --- a/include/xen/interface/features.h +++ b/include/xen/interface/features.h | |||
@@ -38,6 +38,9 @@ | |||
38 | */ | 38 | */ |
39 | #define XENFEAT_pae_pgdir_above_4gb 4 | 39 | #define XENFEAT_pae_pgdir_above_4gb 4 |
40 | 40 | ||
41 | /* x86: Does this Xen host support the MMU_PT_UPDATE_PRESERVE_AD hypercall? */ | ||
42 | #define XENFEAT_mmu_pt_update_preserve_ad 5 | ||
43 | |||
41 | #define XENFEAT_NR_SUBMAPS 1 | 44 | #define XENFEAT_NR_SUBMAPS 1 |
42 | 45 | ||
43 | #endif /* __XEN_PUBLIC_FEATURES_H__ */ | 46 | #endif /* __XEN_PUBLIC_FEATURES_H__ */ |
diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h index 819a0331cda9..2befa3e2f1bc 100644 --- a/include/xen/interface/xen.h +++ b/include/xen/interface/xen.h | |||
@@ -114,9 +114,14 @@ | |||
114 | * ptr[:2] -- Machine address within the frame whose mapping to modify. | 114 | * ptr[:2] -- Machine address within the frame whose mapping to modify. |
115 | * The frame must belong to the FD, if one is specified. | 115 | * The frame must belong to the FD, if one is specified. |
116 | * val -- Value to write into the mapping entry. | 116 | * val -- Value to write into the mapping entry. |
117 | * | ||
118 | * ptr[1:0] == MMU_PT_UPDATE_PRESERVE_AD: | ||
119 | * As MMU_NORMAL_PT_UPDATE above, but A/D bits currently in the PTE are ORed | ||
120 | * with those in @val. | ||
117 | */ | 121 | */ |
118 | #define MMU_NORMAL_PT_UPDATE 0 /* checked '*ptr = val'. ptr is MA. */ | 122 | #define MMU_NORMAL_PT_UPDATE 0 /* checked '*ptr = val'. ptr is MA. */ |
119 | #define MMU_MACHPHYS_UPDATE 1 /* ptr = MA of frame to modify entry for */ | 123 | #define MMU_MACHPHYS_UPDATE 1 /* ptr = MA of frame to modify entry for */ |
124 | #define MMU_PT_UPDATE_PRESERVE_AD 2 /* atomically: *ptr = val | (*ptr&(A|D)) */ | ||
120 | 125 | ||
121 | /* | 126 | /* |
122 | * MMU EXTENDED OPERATIONS | 127 | * MMU EXTENDED OPERATIONS |