aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/xen/enlighten.c13
-rw-r--r--arch/x86/xen/mmu.c21
-rw-r--r--arch/x86/xen/mmu.h4
-rw-r--r--include/xen/interface/features.h3
-rw-r--r--include/xen/interface/xen.h9
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
174static void xen_cpuid(unsigned int *ax, unsigned int *bx, 176static 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
326pte_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
332void 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. */
327static pteval_t pte_mfn_to_pfn(pteval_t val) 348static 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);
52void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep); 52void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
53void xen_pmd_clear(pmd_t *pmdp); 53void xen_pmd_clear(pmd_t *pmdp);
54 54
55pte_t xen_ptep_modify_prot_start(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
56void 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