Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 125278
b: refs/heads/master
c: c5fbdff
h: refs/heads/master
v: v3
  • Loading branch information
Hollis Blanchard authored and Avi Kivity committed Dec 31, 2008
1 parent b89ec3b commit 9788df9
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7924bd41097ae8991c6d38cef8b1e4058e30d198
refs/heads/master: c5fbdffbda79254047ec83b09c1a61a3655d052a
6 changes: 6 additions & 0 deletions trunk/arch/powerpc/include/asm/kvm_44x.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ struct kvmppc_vcpu_44x {
/* References to guest pages in the hardware TLB. */
struct kvmppc_44x_shadow_ref shadow_refs[PPC44x_TLB_SIZE];

/* State of the shadow TLB at guest context switch time. */
struct kvmppc_44x_tlbe shadow_tlb[PPC44x_TLB_SIZE];
u8 shadow_tlb_mod[PPC44x_TLB_SIZE];

struct kvm_vcpu vcpu;
};

Expand All @@ -51,5 +55,7 @@ static inline struct kvmppc_vcpu_44x *to_44x(struct kvm_vcpu *vcpu)
}

void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 new_pid);
void kvmppc_44x_tlb_put(struct kvm_vcpu *vcpu);
void kvmppc_44x_tlb_load(struct kvm_vcpu *vcpu);

#endif /* __ASM_44X_H__ */
7 changes: 2 additions & 5 deletions trunk/arch/powerpc/kvm/44x.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,12 @@ void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu)

void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{
kvmppc_44x_tlb_load(vcpu);
}

void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu)
{
/* XXX Since every guest uses TS=1 TID=0/1 mappings, we can't leave any TLB
* entries around when we're descheduled, so we must completely flush the
* TLB of all guest mappings. On the other hand, if there is only one
* guest, this flush is completely unnecessary. */
_tlbia();
kvmppc_44x_tlb_put(vcpu);
}

int kvmppc_core_check_processor_compat(void)
Expand Down
58 changes: 58 additions & 0 deletions trunk/arch/powerpc/kvm/44x_tlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,25 @@ static inline void kvmppc_44x_tlbie(unsigned int index)
);
}

static inline void kvmppc_44x_tlbre(unsigned int index,
struct kvmppc_44x_tlbe *tlbe)
{
asm volatile(
"tlbre %[word0], %[index], 0\n"
"mfspr %[tid], %[sprn_mmucr]\n"
"andi. %[tid], %[tid], 0xff\n"
"tlbre %[word1], %[index], 1\n"
"tlbre %[word2], %[index], 2\n"
: [word0] "=r"(tlbe->word0),
[word1] "=r"(tlbe->word1),
[word2] "=r"(tlbe->word2),
[tid] "=r"(tlbe->tid)
: [index] "r"(index),
[sprn_mmucr] "i"(SPRN_MMUCR)
: "cc"
);
}

static inline void kvmppc_44x_tlbwe(unsigned int index,
struct kvmppc_44x_tlbe *stlbe)
{
Expand Down Expand Up @@ -116,6 +135,44 @@ static u32 kvmppc_44x_tlb_shadow_attrib(u32 attrib, int usermode)
return attrib;
}

/* Load shadow TLB back into hardware. */
void kvmppc_44x_tlb_load(struct kvm_vcpu *vcpu)
{
struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu);
int i;

for (i = 0; i <= tlb_44x_hwater; i++) {
struct kvmppc_44x_tlbe *stlbe = &vcpu_44x->shadow_tlb[i];

if (get_tlb_v(stlbe) && get_tlb_ts(stlbe))
kvmppc_44x_tlbwe(i, stlbe);
}
}

static void kvmppc_44x_tlbe_set_modified(struct kvmppc_vcpu_44x *vcpu_44x,
unsigned int i)
{
vcpu_44x->shadow_tlb_mod[i] = 1;
}

/* Save hardware TLB to the vcpu, and invalidate all guest mappings. */
void kvmppc_44x_tlb_put(struct kvm_vcpu *vcpu)
{
struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu);
int i;

for (i = 0; i <= tlb_44x_hwater; i++) {
struct kvmppc_44x_tlbe *stlbe = &vcpu_44x->shadow_tlb[i];

if (vcpu_44x->shadow_tlb_mod[i])
kvmppc_44x_tlbre(i, stlbe);

if (get_tlb_v(stlbe) && get_tlb_ts(stlbe))
kvmppc_44x_tlbie(i);
}
}


/* Search the guest TLB for a matching entry. */
int kvmppc_44x_tlb_index(struct kvm_vcpu *vcpu, gva_t eaddr, unsigned int pid,
unsigned int as)
Expand Down Expand Up @@ -283,6 +340,7 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gpa_t gpaddr, u64 asid,
ref->tid = stlbe.tid;

/* Insert shadow mapping into hardware TLB. */
kvmppc_44x_tlbe_set_modified(vcpu_44x, victim);
kvmppc_44x_tlbwe(victim, &stlbe);
KVMTRACE_5D(STLB_WRITE, vcpu, victim, stlbe.tid, stlbe.word0, stlbe.word1,
stlbe.word2, handler);
Expand Down

0 comments on commit 9788df9

Please sign in to comment.