Commit 0164c0f0 authored by Scott Wood's avatar Scott Wood Committed by Avi Kivity

KVM: PPC: e500: clear up confusion between host and guest entries

Split out the portions of tlbe_priv that should be associated with host
entries into tlbe_ref.  Base victim selection on the number of hardware
entries, not guest entries.

For TLB1, where one guest entry can be mapped by multiple host entries,
we use the host tlbe_ref for tracking page references.  For the guest
TLB0 entries, we still track it with gtlb_priv, to avoid having to
retranslate if the entry is evicted from the host TLB but not the
guest TLB.
Signed-off-by: default avatarScott Wood <scottwood@freescale.com>
Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent 90b92a6f
...@@ -32,13 +32,21 @@ struct tlbe{ ...@@ -32,13 +32,21 @@ struct tlbe{
#define E500_TLB_VALID 1 #define E500_TLB_VALID 1
#define E500_TLB_DIRTY 2 #define E500_TLB_DIRTY 2
struct tlbe_priv { struct tlbe_ref {
pfn_t pfn; pfn_t pfn;
unsigned int flags; /* E500_TLB_* */ unsigned int flags; /* E500_TLB_* */
}; };
struct tlbe_priv {
struct tlbe_ref ref; /* TLB0 only -- TLB1 uses tlb_refs */
};
struct vcpu_id_table; struct vcpu_id_table;
struct kvmppc_e500_tlb_params {
int entries, ways, sets;
};
struct kvmppc_vcpu_e500 { struct kvmppc_vcpu_e500 {
/* Unmodified copy of the guest's TLB. */ /* Unmodified copy of the guest's TLB. */
struct tlbe *gtlb_arch[E500_TLB_NUM]; struct tlbe *gtlb_arch[E500_TLB_NUM];
...@@ -49,6 +57,20 @@ struct kvmppc_vcpu_e500 { ...@@ -49,6 +57,20 @@ struct kvmppc_vcpu_e500 {
unsigned int gtlb_size[E500_TLB_NUM]; unsigned int gtlb_size[E500_TLB_NUM];
unsigned int gtlb_nv[E500_TLB_NUM]; unsigned int gtlb_nv[E500_TLB_NUM];
/*
* information associated with each host TLB entry --
* TLB1 only for now. If/when guest TLB1 entries can be
* mapped with host TLB0, this will be used for that too.
*
* We don't want to use this for guest TLB0 because then we'd
* have the overhead of doing the translation again even if
* the entry is still in the guest TLB (e.g. we swapped out
* and back, and our host TLB entries got evicted).
*/
struct tlbe_ref *tlb_refs[E500_TLB_NUM];
unsigned int host_tlb1_nv;
u32 host_pid[E500_PID_NUM]; u32 host_pid[E500_PID_NUM];
u32 pid[E500_PID_NUM]; u32 pid[E500_PID_NUM];
u32 svr; u32 svr;
......
...@@ -167,6 +167,7 @@ ...@@ -167,6 +167,7 @@
#define TLBnCFG_MAXSIZE 0x000f0000 /* Maximum Page Size (v1.0) */ #define TLBnCFG_MAXSIZE 0x000f0000 /* Maximum Page Size (v1.0) */
#define TLBnCFG_MAXSIZE_SHIFT 16 #define TLBnCFG_MAXSIZE_SHIFT 16
#define TLBnCFG_ASSOC 0xff000000 /* Associativity */ #define TLBnCFG_ASSOC 0xff000000 /* Associativity */
#define TLBnCFG_ASSOC_SHIFT 24
/* TLBnPS encoding */ /* TLBnPS encoding */
#define TLBnPS_4K 0x00000004 #define TLBnPS_4K 0x00000004
......
This diff is collapsed.
...@@ -155,23 +155,6 @@ static inline unsigned int get_tlb_esel_bit( ...@@ -155,23 +155,6 @@ static inline unsigned int get_tlb_esel_bit(
return (vcpu_e500->mas0 >> 16) & 0xfff; return (vcpu_e500->mas0 >> 16) & 0xfff;
} }
static inline unsigned int get_tlb_esel(
const struct kvmppc_vcpu_e500 *vcpu_e500,
int tlbsel)
{
unsigned int esel = get_tlb_esel_bit(vcpu_e500);
if (tlbsel == 0) {
esel &= KVM_E500_TLB0_WAY_NUM_MASK;
esel |= ((vcpu_e500->mas2 >> 12) & KVM_E500_TLB0_WAY_SIZE_MASK)
<< KVM_E500_TLB0_WAY_NUM_BIT;
} else {
esel &= KVM_E500_TLB1_SIZE - 1;
}
return esel;
}
static inline int tlbe_is_host_safe(const struct kvm_vcpu *vcpu, static inline int tlbe_is_host_safe(const struct kvm_vcpu *vcpu,
const struct tlbe *tlbe) const struct tlbe *tlbe)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment