Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 343458
b: refs/heads/master
c: 862d31f
h: refs/heads/master
v: v3
  • Loading branch information
Alexander Graf committed Oct 5, 2012
1 parent c633d57 commit 63e528c
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 8 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: d69c6436443c05a64452054f51a79316297755f4
refs/heads/master: 862d31f788f9a249f7656d02d8d4006e306108ce
3 changes: 2 additions & 1 deletion trunk/arch/powerpc/include/asm/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
#endif

#ifdef CONFIG_KVM_BOOK3S_64_HV
#if defined(CONFIG_KVM_BOOK3S_64_HV) || defined(CONFIG_KVM_E500V2) || \
defined(CONFIG_KVM_E500MC)
#include <linux/mmu_notifier.h>

#define KVM_ARCH_WANT_MMU_NOTIFIER
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/powerpc/include/asm/kvm_ppc.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
struct kvm_interrupt *irq);
extern void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu,
struct kvm_interrupt *irq);
extern void kvmppc_core_flush_tlb(struct kvm_vcpu *vcpu);

extern int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
unsigned int op, int *advance);
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/powerpc/kvm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ config KVM_E500V2
depends on EXPERIMENTAL && E500 && !PPC_E500MC
select KVM
select KVM_MMIO
select MMU_NOTIFIER
---help---
Support running unmodified E500 guest kernels in virtual machines on
E500v2 host processors.
Expand All @@ -138,6 +139,7 @@ config KVM_E500MC
select KVM
select KVM_MMIO
select KVM_BOOKE_HV
select MMU_NOTIFIER
---help---
Support running unmodified E500MC/E5500 (32-bit) guest kernels in
virtual machines on E500MC/E5500 host processors.
Expand Down
6 changes: 6 additions & 0 deletions trunk/arch/powerpc/kvm/booke.c
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,10 @@ static void kvmppc_check_requests(struct kvm_vcpu *vcpu)
if (vcpu->requests) {
if (kvm_check_request(KVM_REQ_PENDING_TIMER, vcpu))
update_timer_ints(vcpu);
#if defined(CONFIG_KVM_E500V2) || defined(CONFIG_KVM_E500MC)
if (kvm_check_request(KVM_REQ_TLB_FLUSH, vcpu))
kvmppc_core_flush_tlb(vcpu);
#endif
}
}

Expand Down Expand Up @@ -579,6 +583,8 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
#endif

kvm_guest_exit();
vcpu->mode = OUTSIDE_GUEST_MODE;
smp_wmb();

out:
vcpu->mode = OUTSIDE_GUEST_MODE;
Expand Down
60 changes: 54 additions & 6 deletions trunk/arch/powerpc/kvm/e500_tlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,18 +303,15 @@ static inline void kvmppc_e500_ref_setup(struct tlbe_ref *ref,
ref->pfn = pfn;
ref->flags = E500_TLB_VALID;

if (tlbe_is_writable(gtlbe))
if (tlbe_is_writable(gtlbe)) {
ref->flags |= E500_TLB_DIRTY;
kvm_set_pfn_dirty(pfn);
}
}

static inline void kvmppc_e500_ref_release(struct tlbe_ref *ref)
{
if (ref->flags & E500_TLB_VALID) {
if (ref->flags & E500_TLB_DIRTY)
kvm_release_pfn_dirty(ref->pfn);
else
kvm_release_pfn_clean(ref->pfn);

ref->flags = 0;
}
}
Expand Down Expand Up @@ -357,6 +354,13 @@ static void clear_tlb_refs(struct kvmppc_vcpu_e500 *vcpu_e500)
clear_tlb_privs(vcpu_e500);
}

void kvmppc_core_flush_tlb(struct kvm_vcpu *vcpu)
{
struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
clear_tlb_refs(vcpu_e500);
clear_tlb1_bitmap(vcpu_e500);
}

static inline void kvmppc_e500_deliver_tlb_miss(struct kvm_vcpu *vcpu,
unsigned int eaddr, int as)
{
Expand Down Expand Up @@ -541,6 +545,9 @@ static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,

/* Clear i-cache for new pages */
kvmppc_mmu_flush_icache(pfn);

/* Drop refcount on page, so that mmu notifiers can clear it */
kvm_release_pfn_clean(pfn);
}

/* XXX only map the one-one case, for now use TLB0 */
Expand Down Expand Up @@ -1064,6 +1071,47 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 eaddr, gpa_t gpaddr,
write_stlbe(vcpu_e500, gtlbe, &stlbe, stlbsel, sesel);
}

/************* MMU Notifiers *************/

int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
{
/*
* Flush all shadow tlb entries everywhere. This is slow, but
* we are 100% sure that we catch the to be unmapped page
*/
kvm_flush_remote_tlbs(kvm);

return 0;
}

int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end)
{
/* kvm_unmap_hva flushes everything anyways */
kvm_unmap_hva(kvm, start);

return 0;
}

int kvm_age_hva(struct kvm *kvm, unsigned long hva)
{
/* XXX could be more clever ;) */
return 0;
}

int kvm_test_age_hva(struct kvm *kvm, unsigned long hva)
{
/* XXX could be more clever ;) */
return 0;
}

void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte)
{
/* The page will get remapped properly on its next fault */
kvm_unmap_hva(kvm, hva);
}

/*****************************************/

static void free_gtlb(struct kvmppc_vcpu_e500 *vcpu_e500)
{
int i;
Expand Down

0 comments on commit 63e528c

Please sign in to comment.