Skip to content

Commit 41f07a1

Browse files
gaosong-loongsonAvenger-285714
authored andcommitted
LoongArch: fix migrate issue
Upstream: no when read_fault, we shoul't set the page _PAGE_WRITE. this may case nest write fault issue. Signed-off-by: Song Gao <gaosong@loongson.cn> Change-Id: I443ac32d152c43635c0bafbe3da9b9479f4e546d Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
1 parent c34a902 commit 41f07a1

2 files changed

Lines changed: 13 additions & 15 deletions

File tree

arch/loongarch/include/asm/kvm_mmu.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,7 @@ static inline void kvm_set_pte(kvm_pte_t *ptep, kvm_pte_t val)
6161
WRITE_ONCE(*ptep, val);
6262
}
6363

64-
static inline int kvm_pte_write(kvm_pte_t pte) { return pte & _PAGE_WRITE; }
65-
static inline int kvm_record_pte_write_able(kvm_pte_t pte) { return pte & KVM_RECORD_PAGE_WRITE_ABLE; }
64+
static inline int kvm_pte_write(kvm_pte_t pte) { return pte & KVM_RECORD_PAGE_WRITE_ABLE; }
6665
static inline int kvm_pte_dirty(kvm_pte_t pte) { return pte & _PAGE_DIRTY; }
6766
static inline int kvm_pte_young(kvm_pte_t pte) { return pte & _PAGE_ACCESSED; }
6867
static inline int kvm_pte_huge(kvm_pte_t pte) { return pte & _PAGE_HUGE; }
@@ -79,7 +78,12 @@ static inline kvm_pte_t kvm_pte_mkold(kvm_pte_t pte)
7978

8079
static inline kvm_pte_t kvm_pte_mkdirty(kvm_pte_t pte)
8180
{
82-
return pte | _PAGE_DIRTY;
81+
return pte | _PAGE_DIRTY | _PAGE_WRITE;
82+
}
83+
84+
static inline kvm_pte_t kvm_pte_mkwrite(kvm_pte_t pte)
85+
{
86+
return pte | KVM_RECORD_PAGE_WRITE_ABLE;
8387
}
8488

8589
static inline kvm_pte_t kvm_pte_mkclean(kvm_pte_t pte)

arch/loongarch/kvm/mmu.c

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -538,8 +538,10 @@ bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
538538
* _PAGE_DIRTY since gpa has already recorded as dirty page
539539
*/
540540
prot_bits |= __WRITEABLE & *ptep & pte_val(range->arg.pte);
541-
if (prot_bits & _PAGE_WRITE)
542-
prot_bits |= KVM_RECORD_PAGE_WRITE_ABLE;
541+
if (kvm_pte_dirty(prot_bits)) {
542+
prot_bits = kvm_pte_mkclean(prot_bits);
543+
prot_bits = kvm_pte_mkwrite(prot_bits);
544+
}
543545
kvm_set_pte(ptep, kvm_pfn_pte(pfn, __pgprot(prot_bits)));
544546

545547
return true;
@@ -605,15 +607,7 @@ static int kvm_map_page_fast(struct kvm_vcpu *vcpu, unsigned long gpa, bool writ
605607
/* Track access to pages marked old */
606608
new = kvm_pte_mkyoung(*ptep);
607609

608-
/* We restore the write property of
609-
* the page table entry according to
610-
* KVM_RECORD_PAGE_WRITE_ABLE
611-
*/
612-
if (kvm_record_pte_write_able(new))
613-
new |= _PAGE_WRITE;
614-
615610
/* call kvm_set_pfn_accessed() after unlock */
616-
617611
if (write && !kvm_pte_dirty(new)) {
618612
if (!kvm_pte_write(new)) {
619613
ret = -EFAULT;
@@ -918,9 +912,9 @@ static int kvm_map_page(struct kvm_vcpu *vcpu, unsigned long gpa, bool write)
918912
* to record it to restore the write attribute of the page entry,
919913
* in the fast path kvm_map_page_fast for page table processing
920914
*/
921-
prot_bits |= _PAGE_WRITE | KVM_RECORD_PAGE_WRITE_ABLE;
915+
prot_bits = kvm_pte_mkwrite(prot_bits);
922916
if (write)
923-
prot_bits |= __WRITEABLE;
917+
prot_bits = kvm_pte_mkdirty(prot_bits);
924918
}
925919

926920
/* Disable dirty logging on HugePages */

0 commit comments

Comments
 (0)