Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 133699
b: refs/heads/master
c: bc8080c
h: refs/heads/master
i:
  133697: 5bacc33
  133695: 3286118
v: v3
  • Loading branch information
Hollis Blanchard authored and Avi Kivity committed Mar 24, 2009
1 parent e943104 commit 9dfc3e8
Show file tree
Hide file tree
Showing 8 changed files with 1,331 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 17c885eb5c38f39a2bb3143a67687bd905dcd0fa
refs/heads/master: bc8080cbcc8870178f0910edd537d0cb5706d703
67 changes: 67 additions & 0 deletions trunk/arch/powerpc/include/asm/kvm_e500.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
*
* Author: Yu Liu, <yu.liu@freescale.com>
*
* Description:
* This file is derived from arch/powerpc/include/asm/kvm_44x.h,
* by Hollis Blanchard <hollisb@us.ibm.com>.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as
* published by the Free Software Foundation.
*/

#ifndef __ASM_KVM_E500_H__
#define __ASM_KVM_E500_H__

#include <linux/kvm_host.h>

#define BOOKE_INTERRUPT_SIZE 36

#define E500_PID_NUM 3
#define E500_TLB_NUM 2

struct tlbe{
u32 mas1;
u32 mas2;
u32 mas3;
u32 mas7;
};

struct kvmppc_vcpu_e500 {
/* Unmodified copy of the guest's TLB. */
struct tlbe *guest_tlb[E500_TLB_NUM];
/* TLB that's actually used when the guest is running. */
struct tlbe *shadow_tlb[E500_TLB_NUM];
/* Pages which are referenced in the shadow TLB. */
struct page **shadow_pages[E500_TLB_NUM];

unsigned int guest_tlb_size[E500_TLB_NUM];
unsigned int shadow_tlb_size[E500_TLB_NUM];
unsigned int guest_tlb_nv[E500_TLB_NUM];

u32 host_pid[E500_PID_NUM];
u32 pid[E500_PID_NUM];

u32 mas0;
u32 mas1;
u32 mas2;
u32 mas3;
u32 mas4;
u32 mas5;
u32 mas6;
u32 mas7;
u32 l1csr1;
u32 hid0;
u32 hid1;

struct kvm_vcpu vcpu;
};

static inline struct kvmppc_vcpu_e500 *to_e500(struct kvm_vcpu *vcpu)
{
return container_of(vcpu, struct kvmppc_vcpu_e500, vcpu);
}

#endif /* __ASM_KVM_E500_H__ */
13 changes: 13 additions & 0 deletions trunk/arch/powerpc/kvm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,19 @@ config KVM_EXIT_TIMING

If unsure, say N.

config KVM_E500
bool "KVM support for PowerPC E500 processors"
depends on EXPERIMENTAL && E500
select KVM
---help---
Support running unmodified E500 guest kernels in virtual machines on
E500 host processors.

This module provides access to the hardware capabilities through
a character device node named /dev/kvm.

If unsure, say N.

config KVM_TRACE
bool "KVM trace support"
depends on KVM && MARKERS && SYSFS
Expand Down
9 changes: 9 additions & 0 deletions trunk/arch/powerpc/kvm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,12 @@ kvm-440-objs := \
44x_tlb.o \
44x_emulate.o
obj-$(CONFIG_KVM_440) += kvm-440.o

kvm-e500-objs := \
booke.o \
booke_emulate.o \
booke_interrupts.o \
e500.o \
e500_tlb.o \
e500_emulate.o
obj-$(CONFIG_KVM_E500) += kvm-e500.o
151 changes: 151 additions & 0 deletions trunk/arch/powerpc/kvm/e500.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/*
* Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
*
* Author: Yu Liu, <yu.liu@freescale.com>
*
* Description:
* This file is derived from arch/powerpc/kvm/44x.c,
* by Hollis Blanchard <hollisb@us.ibm.com>.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as
* published by the Free Software Foundation.
*/

#include <linux/kvm_host.h>
#include <linux/err.h>

#include <asm/reg.h>
#include <asm/cputable.h>
#include <asm/tlbflush.h>
#include <asm/kvm_e500.h>
#include <asm/kvm_ppc.h>

#include "e500_tlb.h"

void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu)
{
}

void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu)
{
}

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

void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu)
{
kvmppc_e500_tlb_put(vcpu);
}

int kvmppc_core_check_processor_compat(void)
{
int r;

if (strcmp(cur_cpu_spec->cpu_name, "e500v2") == 0)
r = 0;
else
r = -ENOTSUPP;

return r;
}

int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
{
struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);

kvmppc_e500_tlb_setup(vcpu_e500);

/* Use the same core vertion as host's */
vcpu->arch.pvr = mfspr(SPRN_PVR);

return 0;
}

/* 'linear_address' is actually an encoding of AS|PID|EADDR . */
int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
struct kvm_translation *tr)
{
int index;
gva_t eaddr;
u8 pid;
u8 as;

eaddr = tr->linear_address;
pid = (tr->linear_address >> 32) & 0xff;
as = (tr->linear_address >> 40) & 0x1;

index = kvmppc_e500_tlb_search(vcpu, eaddr, pid, as);
if (index < 0) {
tr->valid = 0;
return 0;
}

tr->physical_address = kvmppc_mmu_xlate(vcpu, index, eaddr);
/* XXX what does "writeable" and "usermode" even mean? */
tr->valid = 1;

return 0;
}

struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
{
struct kvmppc_vcpu_e500 *vcpu_e500;
struct kvm_vcpu *vcpu;
int err;

vcpu_e500 = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
if (!vcpu_e500) {
err = -ENOMEM;
goto out;
}

vcpu = &vcpu_e500->vcpu;
err = kvm_vcpu_init(vcpu, kvm, id);
if (err)
goto free_vcpu;

err = kvmppc_e500_tlb_init(vcpu_e500);
if (err)
goto uninit_vcpu;

return vcpu;

uninit_vcpu:
kvm_vcpu_uninit(vcpu);
free_vcpu:
kmem_cache_free(kvm_vcpu_cache, vcpu_e500);
out:
return ERR_PTR(err);
}

void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
{
struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);

kvmppc_e500_tlb_uninit(vcpu_e500);
kvm_vcpu_uninit(vcpu);
kmem_cache_free(kvm_vcpu_cache, vcpu_e500);
}

static int kvmppc_e500_init(void)
{
int r;

r = kvmppc_booke_init();
if (r)
return r;

return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), THIS_MODULE);
}

static void kvmppc_e500_exit(void)
{
kvmppc_booke_exit();
}

module_init(kvmppc_e500_init);
module_exit(kvmppc_e500_exit);
Loading

0 comments on commit 9dfc3e8

Please sign in to comment.