Skip to content

Commit f2104bf

Browse files
committed
KVM: e500: track host-writability of pages
Add the possibility of marking a page so that the UW and SW bits are force-cleared. This is stored in the private info so that it persists across multiple calls to kvmppc_e500_setup_stlbe. Signed-off-by: Paolo Bonzini <[email protected]>
1 parent e97fbb4 commit f2104bf

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

arch/powerpc/kvm/e500.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ enum vcpu_ftr {
3434
#define E500_TLB_BITMAP (1 << 30)
3535
/* TLB1 entry is mapped by host TLB0 */
3636
#define E500_TLB_TLB0 (1 << 29)
37+
/* entry is writable on the host */
38+
#define E500_TLB_WRITABLE (1 << 28)
3739
/* bits [6-5] MAS2_X1 and MAS2_X0 and [4-0] bits for WIMGE */
3840
#define E500_TLB_MAS2_ATTR (0x7f)
3941

arch/powerpc/kvm/e500_mmu_host.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,14 @@ static inline unsigned int tlb1_max_shadow_size(void)
4545
return host_tlb_params[1].entries - tlbcam_index - 1;
4646
}
4747

48-
static inline u32 e500_shadow_mas3_attrib(u32 mas3, int usermode)
48+
static inline u32 e500_shadow_mas3_attrib(u32 mas3, bool writable, int usermode)
4949
{
5050
/* Mask off reserved bits. */
5151
mas3 &= MAS3_ATTRIB_MASK;
5252

53+
if (!writable)
54+
mas3 &= ~(MAS3_UW|MAS3_SW);
55+
5356
#ifndef CONFIG_KVM_BOOKE_HV
5457
if (!usermode) {
5558
/* Guest is in supervisor mode,
@@ -244,10 +247,13 @@ static inline int tlbe_is_writable(struct kvm_book3e_206_tlb_entry *tlbe)
244247

245248
static inline void kvmppc_e500_ref_setup(struct tlbe_ref *ref,
246249
struct kvm_book3e_206_tlb_entry *gtlbe,
247-
kvm_pfn_t pfn, unsigned int wimg)
250+
kvm_pfn_t pfn, unsigned int wimg,
251+
bool writable)
248252
{
249253
ref->pfn = pfn;
250254
ref->flags = E500_TLB_VALID;
255+
if (writable)
256+
ref->flags |= E500_TLB_WRITABLE;
251257

252258
/* Use guest supplied MAS2_G and MAS2_E */
253259
ref->flags |= (gtlbe->mas2 & MAS2_ATTRIB_MASK) | wimg;
@@ -303,14 +309,15 @@ static void kvmppc_e500_setup_stlbe(
303309
{
304310
kvm_pfn_t pfn = ref->pfn;
305311
u32 pr = vcpu->arch.shared->msr & MSR_PR;
312+
bool writable = !!(ref->flags & E500_TLB_WRITABLE);
306313

307314
BUG_ON(!(ref->flags & E500_TLB_VALID));
308315

309316
/* Force IPROT=0 for all guest mappings. */
310317
stlbe->mas1 = MAS1_TSIZE(tsize) | get_tlb_sts(gtlbe) | MAS1_VALID;
311318
stlbe->mas2 = (gvaddr & MAS2_EPN) | (ref->flags & E500_TLB_MAS2_ATTR);
312319
stlbe->mas7_3 = ((u64)pfn << PAGE_SHIFT) |
313-
e500_shadow_mas3_attrib(gtlbe->mas7_3, pr);
320+
e500_shadow_mas3_attrib(gtlbe->mas7_3, writable, pr);
314321
}
315322

316323
static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
@@ -487,7 +494,7 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
487494
}
488495
local_irq_restore(flags);
489496

490-
kvmppc_e500_ref_setup(ref, gtlbe, pfn, wimg);
497+
kvmppc_e500_ref_setup(ref, gtlbe, pfn, wimg, true);
491498
kvmppc_e500_setup_stlbe(&vcpu_e500->vcpu, gtlbe, tsize,
492499
ref, gvaddr, stlbe);
493500
writable = tlbe_is_writable(stlbe);

0 commit comments

Comments
 (0)