KVM
Macros | Functions
page_track.c File Reference
#include <linux/lockdep.h>
#include <linux/kvm_host.h>
#include <linux/rculist.h>
#include "mmu.h"
#include "mmu_internal.h"
#include "page_track.h"
Include dependency graph for page_track.c:

Go to the source code of this file.

Macros

#define pr_fmt(fmt)   KBUILD_MODNAME ": " fmt
 

Functions

bool kvm_page_track_write_tracking_enabled (struct kvm *kvm)
 
void kvm_page_track_free_memslot (struct kvm_memory_slot *slot)
 
static int __kvm_page_track_write_tracking_alloc (struct kvm_memory_slot *slot, unsigned long npages)
 
int kvm_page_track_create_memslot (struct kvm *kvm, struct kvm_memory_slot *slot, unsigned long npages)
 
int kvm_page_track_write_tracking_alloc (struct kvm_memory_slot *slot)
 
static void update_gfn_write_track (struct kvm_memory_slot *slot, gfn_t gfn, short count)
 
void __kvm_write_track_add_gfn (struct kvm *kvm, struct kvm_memory_slot *slot, gfn_t gfn)
 
void __kvm_write_track_remove_gfn (struct kvm *kvm, struct kvm_memory_slot *slot, gfn_t gfn)
 
bool kvm_gfn_is_write_tracked (struct kvm *kvm, const struct kvm_memory_slot *slot, gfn_t gfn)
 

Macro Definition Documentation

◆ pr_fmt

#define pr_fmt (   fmt)    KBUILD_MODNAME ": " fmt

Definition at line 13 of file page_track.c.

Function Documentation

◆ __kvm_page_track_write_tracking_alloc()

static int __kvm_page_track_write_tracking_alloc ( struct kvm_memory_slot *  slot,
unsigned long  npages 
)
static

Definition at line 35 of file page_track.c.

37 {
38  const size_t size = sizeof(*slot->arch.gfn_write_track);
39 
40  if (!slot->arch.gfn_write_track)
41  slot->arch.gfn_write_track = __vcalloc(npages, size,
42  GFP_KERNEL_ACCOUNT);
43 
44  return slot->arch.gfn_write_track ? 0 : -ENOMEM;
45 }
Here is the caller graph for this function:

◆ __kvm_write_track_add_gfn()

void __kvm_write_track_add_gfn ( struct kvm *  kvm,
struct kvm_memory_slot *  slot,
gfn_t  gfn 
)

Definition at line 77 of file page_track.c.

79 {
80  lockdep_assert_held_write(&kvm->mmu_lock);
81 
82  lockdep_assert_once(lockdep_is_held(&kvm->slots_lock) ||
83  srcu_read_lock_held(&kvm->srcu));
84 
85  if (KVM_BUG_ON(!kvm_page_track_write_tracking_enabled(kvm), kvm))
86  return;
87 
88  update_gfn_write_track(slot, gfn, 1);
89 
90  /*
91  * new track stops large page mapping for the
92  * tracked page.
93  */
94  kvm_mmu_gfn_disallow_lpage(slot, gfn);
95 
96  if (kvm_mmu_slot_gfn_write_protect(kvm, slot, gfn, PG_LEVEL_4K))
98 }
void kvm_flush_remote_tlbs(struct kvm *kvm)
Definition: kvm_main.c:346
bool kvm_mmu_slot_gfn_write_protect(struct kvm *kvm, struct kvm_memory_slot *slot, u64 gfn, int min_level)
Definition: mmu.c:1414
void kvm_mmu_gfn_disallow_lpage(const struct kvm_memory_slot *slot, gfn_t gfn)
Definition: mmu.c:817
bool kvm_page_track_write_tracking_enabled(struct kvm *kvm)
Definition: page_track.c:23
static void update_gfn_write_track(struct kvm_memory_slot *slot, gfn_t gfn, short count)
Definition: page_track.c:62
Here is the call graph for this function:
Here is the caller graph for this function:

◆ __kvm_write_track_remove_gfn()

void __kvm_write_track_remove_gfn ( struct kvm *  kvm,
struct kvm_memory_slot *  slot,
gfn_t  gfn 
)

Definition at line 100 of file page_track.c.

102 {
103  lockdep_assert_held_write(&kvm->mmu_lock);
104 
105  lockdep_assert_once(lockdep_is_held(&kvm->slots_lock) ||
106  srcu_read_lock_held(&kvm->srcu));
107 
108  if (KVM_BUG_ON(!kvm_page_track_write_tracking_enabled(kvm), kvm))
109  return;
110 
111  update_gfn_write_track(slot, gfn, -1);
112 
113  /*
114  * allow large page mapping for the tracked page
115  * after the tracker is gone.
116  */
117  kvm_mmu_gfn_allow_lpage(slot, gfn);
118 }
void kvm_mmu_gfn_allow_lpage(const struct kvm_memory_slot *slot, gfn_t gfn)
Definition: mmu.c:822
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kvm_gfn_is_write_tracked()

bool kvm_gfn_is_write_tracked ( struct kvm *  kvm,
const struct kvm_memory_slot *  slot,
gfn_t  gfn 
)

Definition at line 123 of file page_track.c.

125 {
126  int index;
127 
128  if (!slot)
129  return false;
130 
132  return false;
133 
134  index = gfn_to_index(gfn, slot->base_gfn, PG_LEVEL_4K);
135  return !!READ_ONCE(slot->arch.gfn_write_track[index]);
136 }
static gfn_t gfn_to_index(gfn_t gfn, gfn_t base_gfn, int level)
Definition: mmu.h:284
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kvm_page_track_create_memslot()

int kvm_page_track_create_memslot ( struct kvm *  kvm,
struct kvm_memory_slot *  slot,
unsigned long  npages 
)

Definition at line 47 of file page_track.c.

50 {
52  return 0;
53 
54  return __kvm_page_track_write_tracking_alloc(slot, npages);
55 }
static int __kvm_page_track_write_tracking_alloc(struct kvm_memory_slot *slot, unsigned long npages)
Definition: page_track.c:35
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kvm_page_track_free_memslot()

void kvm_page_track_free_memslot ( struct kvm_memory_slot *  slot)

Definition at line 29 of file page_track.c.

30 {
31  kvfree(slot->arch.gfn_write_track);
32  slot->arch.gfn_write_track = NULL;
33 }
Here is the caller graph for this function:

◆ kvm_page_track_write_tracking_alloc()

int kvm_page_track_write_tracking_alloc ( struct kvm_memory_slot *  slot)

Definition at line 57 of file page_track.c.

58 {
59  return __kvm_page_track_write_tracking_alloc(slot, slot->npages);
60 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kvm_page_track_write_tracking_enabled()

bool kvm_page_track_write_tracking_enabled ( struct kvm *  kvm)

Definition at line 23 of file page_track.c.

24 {
25  return IS_ENABLED(CONFIG_KVM_EXTERNAL_WRITE_TRACKING) ||
27 }
bool tdp_enabled
Definition: mmu.c:106
static bool kvm_shadow_root_allocated(struct kvm *kvm)
Definition: mmu.h:262
Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_gfn_write_track()

static void update_gfn_write_track ( struct kvm_memory_slot *  slot,
gfn_t  gfn,
short  count 
)
static

Definition at line 62 of file page_track.c.

64 {
65  int index, val;
66 
67  index = gfn_to_index(gfn, slot->base_gfn, PG_LEVEL_4K);
68 
69  val = slot->arch.gfn_write_track[index];
70 
71  if (WARN_ON_ONCE(val + count < 0 || val + count > USHRT_MAX))
72  return;
73 
74  slot->arch.gfn_write_track[index] += count;
75 }
Here is the call graph for this function:
Here is the caller graph for this function: