Skip to content

Commit 9cb1096

Browse files
Gavin ShanMarc Zyngier
authored andcommitted
KVM: arm64: Enable ring-based dirty memory tracking
Enable ring-based dirty memory tracking on ARM64: - Enable CONFIG_HAVE_KVM_DIRTY_RING_ACQ_REL. - Enable CONFIG_NEED_KVM_DIRTY_RING_WITH_BITMAP. - Set KVM_DIRTY_LOG_PAGE_OFFSET for the ring buffer's physical page offset. - Add ARM64 specific kvm_arch_allow_write_without_running_vcpu() to keep the site of saving vgic/its tables out of the no-running-vcpu radar. Signed-off-by: Gavin Shan <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 86bdf3e commit 9cb1096

File tree

6 files changed

+28
-1
lines changed

6 files changed

+28
-1
lines changed

Documentation/virt/kvm/api.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7921,7 +7921,7 @@ regardless of what has actually been exposed through the CPUID leaf.
79217921
8.29 KVM_CAP_DIRTY_LOG_RING/KVM_CAP_DIRTY_LOG_RING_ACQ_REL
79227922
----------------------------------------------------------
79237923

7924-
:Architectures: x86
7924+
:Architectures: x86, arm64
79257925
:Parameters: args[0] - size of the dirty log ring
79267926

79277927
KVM is capable of tracking dirty memory using ring buffers that are

arch/arm64/include/uapi/asm/kvm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#define __KVM_HAVE_VCPU_EVENTS
4444

4545
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
46+
#define KVM_DIRTY_LOG_PAGE_OFFSET 64
4647

4748
#define KVM_REG_SIZE(id) \
4849
(1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))

arch/arm64/kvm/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ menuconfig KVM
3232
select KVM_VFIO
3333
select HAVE_KVM_EVENTFD
3434
select HAVE_KVM_IRQFD
35+
select HAVE_KVM_DIRTY_RING_ACQ_REL
36+
select NEED_KVM_DIRTY_RING_WITH_BITMAP
3537
select HAVE_KVM_MSI
3638
select HAVE_KVM_IRQCHIP
3739
select HAVE_KVM_IRQ_ROUTING

arch/arm64/kvm/arm.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,9 @@ static int check_vcpu_requests(struct kvm_vcpu *vcpu)
746746

747747
if (kvm_check_request(KVM_REQ_SUSPEND, vcpu))
748748
return kvm_vcpu_suspend(vcpu);
749+
750+
if (kvm_dirty_ring_check_request(vcpu))
751+
return 0;
749752
}
750753

751754
return 1;

arch/arm64/kvm/vgic/vgic-its.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2743,6 +2743,7 @@ static int vgic_its_has_attr(struct kvm_device *dev,
27432743
static int vgic_its_ctrl(struct kvm *kvm, struct vgic_its *its, u64 attr)
27442744
{
27452745
const struct vgic_its_abi *abi = vgic_its_get_abi(its);
2746+
struct vgic_dist *dist = &kvm->arch.vgic;
27462747
int ret = 0;
27472748

27482749
if (attr == KVM_DEV_ARM_VGIC_CTRL_INIT) /* Nothing to do */
@@ -2762,7 +2763,9 @@ static int vgic_its_ctrl(struct kvm *kvm, struct vgic_its *its, u64 attr)
27622763
vgic_its_reset(kvm, its);
27632764
break;
27642765
case KVM_DEV_ARM_ITS_SAVE_TABLES:
2766+
dist->save_its_tables_in_progress = true;
27652767
ret = abi->save_tables(its);
2768+
dist->save_its_tables_in_progress = false;
27662769
break;
27672770
case KVM_DEV_ARM_ITS_RESTORE_TABLES:
27682771
ret = abi->restore_tables(its);
@@ -2775,6 +2778,23 @@ static int vgic_its_ctrl(struct kvm *kvm, struct vgic_its *its, u64 attr)
27752778
return ret;
27762779
}
27772780

2781+
/*
2782+
* kvm_arch_allow_write_without_running_vcpu - allow writing guest memory
2783+
* without the running VCPU when dirty ring is enabled.
2784+
*
2785+
* The running VCPU is required to track dirty guest pages when dirty ring
2786+
* is enabled. Otherwise, the backup bitmap should be used to track the
2787+
* dirty guest pages. When vgic/its tables are being saved, the backup
2788+
* bitmap is used to track the dirty guest pages due to the missed running
2789+
* VCPU in the period.
2790+
*/
2791+
bool kvm_arch_allow_write_without_running_vcpu(struct kvm *kvm)
2792+
{
2793+
struct vgic_dist *dist = &kvm->arch.vgic;
2794+
2795+
return dist->save_its_tables_in_progress;
2796+
}
2797+
27782798
static int vgic_its_set_attr(struct kvm_device *dev,
27792799
struct kvm_device_attr *attr)
27802800
{

include/kvm/arm_vgic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ struct vgic_dist {
263263
struct vgic_io_device dist_iodev;
264264

265265
bool has_its;
266+
bool save_its_tables_in_progress;
266267

267268
/*
268269
* Contains the attributes and gpa of the LPI configuration table.

0 commit comments

Comments
 (0)