|
@@ -528,27 +528,19 @@ static void mmu_spte_set(u64 *sptep, u64 new_spte)
|
|
|
__set_spte(sptep, new_spte);
|
|
|
}
|
|
|
|
|
|
-/* Rules for using mmu_spte_update:
|
|
|
- * Update the state bits, it means the mapped pfn is not changed.
|
|
|
- *
|
|
|
- * Whenever we overwrite a writable spte with a read-only one we
|
|
|
- * should flush remote TLBs. Otherwise rmap_write_protect
|
|
|
- * will find a read-only spte, even though the writable spte
|
|
|
- * might be cached on a CPU's TLB, the return value indicates this
|
|
|
- * case.
|
|
|
- *
|
|
|
- * Returns true if the TLB needs to be flushed
|
|
|
+/*
|
|
|
+ * Update the SPTE (excluding the PFN), but do not track changes in its
|
|
|
+ * accessed/dirty status.
|
|
|
*/
|
|
|
-static bool mmu_spte_update(u64 *sptep, u64 new_spte)
|
|
|
+static u64 mmu_spte_update_no_track(u64 *sptep, u64 new_spte)
|
|
|
{
|
|
|
u64 old_spte = *sptep;
|
|
|
- bool flush = false;
|
|
|
|
|
|
WARN_ON(!is_shadow_present_pte(new_spte));
|
|
|
|
|
|
if (!is_shadow_present_pte(old_spte)) {
|
|
|
mmu_spte_set(sptep, new_spte);
|
|
|
- return flush;
|
|
|
+ return old_spte;
|
|
|
}
|
|
|
|
|
|
if (!spte_has_volatile_bits(old_spte))
|
|
@@ -558,6 +550,28 @@ static bool mmu_spte_update(u64 *sptep, u64 new_spte)
|
|
|
|
|
|
WARN_ON(spte_to_pfn(old_spte) != spte_to_pfn(new_spte));
|
|
|
|
|
|
+ return old_spte;
|
|
|
+}
|
|
|
+
|
|
|
+/* Rules for using mmu_spte_update:
|
|
|
+ * Update the state bits, it means the mapped pfn is not changed.
|
|
|
+ *
|
|
|
+ * Whenever we overwrite a writable spte with a read-only one we
|
|
|
+ * should flush remote TLBs. Otherwise rmap_write_protect
|
|
|
+ * will find a read-only spte, even though the writable spte
|
|
|
+ * might be cached on a CPU's TLB, the return value indicates this
|
|
|
+ * case.
|
|
|
+ *
|
|
|
+ * Returns true if the TLB needs to be flushed
|
|
|
+ */
|
|
|
+static bool mmu_spte_update(u64 *sptep, u64 new_spte)
|
|
|
+{
|
|
|
+ bool flush = false;
|
|
|
+ u64 old_spte = mmu_spte_update_no_track(sptep, new_spte);
|
|
|
+
|
|
|
+ if (!is_shadow_present_pte(old_spte))
|
|
|
+ return false;
|
|
|
+
|
|
|
/*
|
|
|
* For the spte updated out of mmu-lock is safe, since
|
|
|
* we always atomically update it, see the comments in
|