KVM
Classes | Macros | Functions
tdp_iter.h File Reference
#include <linux/kvm_host.h>
#include "mmu.h"
#include "spte.h"
Include dependency graph for tdp_iter.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  tdp_iter
 

Macros

#define for_each_tdp_pte_min_level(iter, root, min_level, start, end)
 
#define for_each_tdp_pte(iter, root, start, end)    for_each_tdp_pte_min_level(iter, root, PG_LEVEL_4K, start, end)
 

Functions

static u64 kvm_tdp_mmu_read_spte (tdp_ptep_t sptep)
 
static u64 kvm_tdp_mmu_write_spte_atomic (tdp_ptep_t sptep, u64 new_spte)
 
static void __kvm_tdp_mmu_write_spte (tdp_ptep_t sptep, u64 new_spte)
 
static bool kvm_tdp_mmu_spte_need_atomic_write (u64 old_spte, int level)
 
static u64 kvm_tdp_mmu_write_spte (tdp_ptep_t sptep, u64 old_spte, u64 new_spte, int level)
 
static u64 tdp_mmu_clear_spte_bits (tdp_ptep_t sptep, u64 old_spte, u64 mask, int level)
 
tdp_ptep_t spte_to_child_pt (u64 pte, int level)
 
void tdp_iter_start (struct tdp_iter *iter, struct kvm_mmu_page *root, int min_level, gfn_t next_last_level_gfn)
 
void tdp_iter_next (struct tdp_iter *iter)
 
void tdp_iter_restart (struct tdp_iter *iter)
 

Macro Definition Documentation

◆ for_each_tdp_pte

#define for_each_tdp_pte (   iter,
  root,
  start,
  end 
)     for_each_tdp_pte_min_level(iter, root, PG_LEVEL_4K, start, end)

Definition at line 128 of file tdp_iter.h.

◆ for_each_tdp_pte_min_level

#define for_each_tdp_pte_min_level (   iter,
  root,
  min_level,
  start,
  end 
)
Value:
for (tdp_iter_start(&iter, root, min_level, start); \
iter.valid && iter.gfn < end; \
tdp_iter_next(&iter))
void tdp_iter_start(struct tdp_iter *iter, struct kvm_mmu_page *root, int min_level, gfn_t next_last_level_gfn)
Definition: tdp_iter.c:39

Definition at line 123 of file tdp_iter.h.

Function Documentation

◆ __kvm_tdp_mmu_write_spte()

static void __kvm_tdp_mmu_write_spte ( tdp_ptep_t  sptep,
u64  new_spte 
)
inlinestatic

Definition at line 27 of file tdp_iter.h.

28 {
29  WRITE_ONCE(*rcu_dereference(sptep), new_spte);
30 }
Here is the caller graph for this function:

◆ kvm_tdp_mmu_read_spte()

static u64 kvm_tdp_mmu_read_spte ( tdp_ptep_t  sptep)
inlinestatic

Definition at line 17 of file tdp_iter.h.

18 {
19  return READ_ONCE(*rcu_dereference(sptep));
20 }
Here is the caller graph for this function:

◆ kvm_tdp_mmu_spte_need_atomic_write()

static bool kvm_tdp_mmu_spte_need_atomic_write ( u64  old_spte,
int  level 
)
inlinestatic

Definition at line 44 of file tdp_iter.h.

45 {
46  return is_shadow_present_pte(old_spte) &&
47  is_last_spte(old_spte, level) &&
48  spte_has_volatile_bits(old_spte);
49 }
bool spte_has_volatile_bits(u64 spte)
Definition: spte.c:114
static bool is_last_spte(u64 pte, int level)
Definition: spte.h:318
static bool is_shadow_present_pte(u64 pte)
Definition: spte.h:258
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kvm_tdp_mmu_write_spte()

static u64 kvm_tdp_mmu_write_spte ( tdp_ptep_t  sptep,
u64  old_spte,
u64  new_spte,
int  level 
)
inlinestatic

Definition at line 51 of file tdp_iter.h.

53 {
54  if (kvm_tdp_mmu_spte_need_atomic_write(old_spte, level))
55  return kvm_tdp_mmu_write_spte_atomic(sptep, new_spte);
56 
57  __kvm_tdp_mmu_write_spte(sptep, new_spte);
58  return old_spte;
59 }
static u64 kvm_tdp_mmu_write_spte_atomic(tdp_ptep_t sptep, u64 new_spte)
Definition: tdp_iter.h:22
static void __kvm_tdp_mmu_write_spte(tdp_ptep_t sptep, u64 new_spte)
Definition: tdp_iter.h:27
static bool kvm_tdp_mmu_spte_need_atomic_write(u64 old_spte, int level)
Definition: tdp_iter.h:44
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kvm_tdp_mmu_write_spte_atomic()

static u64 kvm_tdp_mmu_write_spte_atomic ( tdp_ptep_t  sptep,
u64  new_spte 
)
inlinestatic

Definition at line 22 of file tdp_iter.h.

23 {
24  return xchg(rcu_dereference(sptep), new_spte);
25 }
Here is the caller graph for this function:

◆ spte_to_child_pt()

tdp_ptep_t spte_to_child_pt ( u64  pte,
int  level 
)

Definition at line 62 of file tdp_iter.c.

63 {
64  /*
65  * There's no child entry if this entry isn't present or is a
66  * last-level entry.
67  */
68  if (!is_shadow_present_pte(spte) || is_last_spte(spte, level))
69  return NULL;
70 
71  return (tdp_ptep_t)__va(spte_to_pfn(spte) << PAGE_SHIFT);
72 }
u64 __rcu * tdp_ptep_t
Definition: mmu_internal.h:50
static kvm_pfn_t spte_to_pfn(u64 pte)
Definition: spte.h:328
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tdp_iter_next()

void tdp_iter_next ( struct tdp_iter iter)

Definition at line 161 of file tdp_iter.c.

162 {
163  if (iter->yielded) {
164  tdp_iter_restart(iter);
165  return;
166  }
167 
168  if (try_step_down(iter))
169  return;
170 
171  do {
172  if (try_step_side(iter))
173  return;
174  } while (try_step_up(iter));
175  iter->valid = false;
176 }
bool yielded
Definition: tdp_iter.h:116
bool valid
Definition: tdp_iter.h:110
static bool try_step_up(struct tdp_iter *iter)
Definition: tdp_iter.c:133
static bool try_step_side(struct tdp_iter *iter)
Definition: tdp_iter.c:110
static bool try_step_down(struct tdp_iter *iter)
Definition: tdp_iter.c:78
void tdp_iter_restart(struct tdp_iter *iter)
Definition: tdp_iter.c:23
Here is the call graph for this function:

◆ tdp_iter_restart()

void tdp_iter_restart ( struct tdp_iter iter)

Definition at line 23 of file tdp_iter.c.

24 {
25  iter->yielded = false;
26  iter->yielded_gfn = iter->next_last_level_gfn;
27  iter->level = iter->root_level;
28 
29  iter->gfn = gfn_round_for_level(iter->next_last_level_gfn, iter->level);
31 
32  iter->valid = true;
33 }
static gfn_t gfn_round_for_level(gfn_t gfn, int level)
Definition: mmu_internal.h:161
int root_level
Definition: tdp_iter.h:97
gfn_t gfn
Definition: tdp_iter.h:95
gfn_t yielded_gfn
Definition: tdp_iter.h:89
int level
Definition: tdp_iter.h:101
gfn_t next_last_level_gfn
Definition: tdp_iter.h:83
static void tdp_iter_refresh_sptep(struct tdp_iter *iter)
Definition: tdp_iter.c:12
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tdp_iter_start()

void tdp_iter_start ( struct tdp_iter iter,
struct kvm_mmu_page root,
int  min_level,
gfn_t  next_last_level_gfn 
)

Definition at line 39 of file tdp_iter.c.

41 {
42  if (WARN_ON_ONCE(!root || (root->role.level < 1) ||
43  (root->role.level > PT64_ROOT_MAX_LEVEL))) {
44  iter->valid = false;
45  return;
46  }
47 
48  iter->next_last_level_gfn = next_last_level_gfn;
49  iter->root_level = root->role.level;
50  iter->min_level = min_level;
51  iter->pt_path[iter->root_level - 1] = (tdp_ptep_t)root->spt;
52  iter->as_id = kvm_mmu_page_as_id(root);
53 
54  tdp_iter_restart(iter);
55 }
static int kvm_mmu_page_as_id(struct kvm_mmu_page *sp)
Definition: mmu_internal.h:143
union kvm_mmu_page_role role
Definition: mmu_internal.h:80
tdp_ptep_t pt_path[PT64_ROOT_MAX_LEVEL]
Definition: tdp_iter.h:91
int as_id
Definition: tdp_iter.h:103
int min_level
Definition: tdp_iter.h:99
Here is the call graph for this function:

◆ tdp_mmu_clear_spte_bits()

static u64 tdp_mmu_clear_spte_bits ( tdp_ptep_t  sptep,
u64  old_spte,
u64  mask,
int  level 
)
inlinestatic

Definition at line 61 of file tdp_iter.h.

63 {
64  atomic64_t *sptep_atomic;
65 
66  if (kvm_tdp_mmu_spte_need_atomic_write(old_spte, level)) {
67  sptep_atomic = (atomic64_t *)rcu_dereference(sptep);
68  return (u64)atomic64_fetch_and(~mask, sptep_atomic);
69  }
70 
71  __kvm_tdp_mmu_write_spte(sptep, old_spte & ~mask);
72  return old_spte;
73 }
Here is the call graph for this function:
Here is the caller graph for this function: