Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 175811
b: refs/heads/master
c: e15a113
h: refs/heads/master
i:
  175809: cacad25
  175807: 9a483ba
v: v3
  • Loading branch information
Alexander Graf authored and Benjamin Herrenschmidt committed Dec 8, 2009
1 parent a90378c commit 0d8665f
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 17 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: c0cefebc0b6ae1bc4c92672223a54e1ee96ea7f0
refs/heads/master: e15a113700324f7fdcee95589875daed2b98a2fe
18 changes: 17 additions & 1 deletion trunk/arch/powerpc/include/asm/kvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,23 @@ struct kvm_regs {

struct kvm_sregs {
__u32 pvr;
char pad[1020];
union {
struct {
__u64 sdr1;
struct {
struct {
__u64 slbe;
__u64 slbv;
} slb[64];
} ppc64;
struct {
__u32 sr[16];
__u64 ibat[8];
__u64 dbat[8];
} ppc32;
} s;
__u8 pad[1020];
} u;
};

struct kvm_fpu {
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/powerpc/include/asm/kvm_asm.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
#define BOOK3S_IRQPRIO_MAX 16

#define BOOK3S_HFLAG_DCBZ32 0x1
#define BOOK3S_HFLAG_SLB 0x2

#define RESUME_FLAG_NV (1<<0) /* Reload guest nonvolatile state? */
#define RESUME_FLAG_HOST (1<<1) /* Resume host? */
Expand Down
3 changes: 3 additions & 0 deletions trunk/arch/powerpc/include/asm/kvm_book3s.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ struct kvmppc_sr {
};

struct kvmppc_bat {
u64 raw;
u32 bepi;
u32 bepi_mask;
bool vs;
Expand Down Expand Up @@ -113,6 +114,8 @@ extern struct kvmppc_pte *kvmppc_mmu_find_pte(struct kvm_vcpu *vcpu, u64 ea, boo
extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr, bool data);
extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr);
extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec);
extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat,
bool upper, u32 val);

extern u32 kvmppc_trampoline_lowmem;
extern u32 kvmppc_trampoline_enter;
Expand Down
49 changes: 49 additions & 0 deletions trunk/arch/powerpc/kvm/book3s.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)

void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr)
{
vcpu->arch.hflags &= ~BOOK3S_HFLAG_SLB;
vcpu->arch.pvr = pvr;
if ((pvr >= 0x330000) && (pvr < 0x70330000)) {
kvmppc_mmu_book3s_64_init(vcpu);
Expand Down Expand Up @@ -762,14 +763,62 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
struct kvm_sregs *sregs)
{
struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu);
int i;

sregs->pvr = vcpu->arch.pvr;

sregs->u.s.sdr1 = to_book3s(vcpu)->sdr1;
if (vcpu->arch.hflags & BOOK3S_HFLAG_SLB) {
for (i = 0; i < 64; i++) {
sregs->u.s.ppc64.slb[i].slbe = vcpu3s->slb[i].orige | i;
sregs->u.s.ppc64.slb[i].slbv = vcpu3s->slb[i].origv;
}
} else {
for (i = 0; i < 16; i++) {
sregs->u.s.ppc32.sr[i] = vcpu3s->sr[i].raw;
sregs->u.s.ppc32.sr[i] = vcpu3s->sr[i].raw;
}
for (i = 0; i < 8; i++) {
sregs->u.s.ppc32.ibat[i] = vcpu3s->ibat[i].raw;
sregs->u.s.ppc32.dbat[i] = vcpu3s->dbat[i].raw;
}
}
return 0;
}

int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
struct kvm_sregs *sregs)
{
struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu);
int i;

kvmppc_set_pvr(vcpu, sregs->pvr);

vcpu3s->sdr1 = sregs->u.s.sdr1;
if (vcpu->arch.hflags & BOOK3S_HFLAG_SLB) {
for (i = 0; i < 64; i++) {
vcpu->arch.mmu.slbmte(vcpu, sregs->u.s.ppc64.slb[i].slbv,
sregs->u.s.ppc64.slb[i].slbe);
}
} else {
for (i = 0; i < 16; i++) {
vcpu->arch.mmu.mtsrin(vcpu, i, sregs->u.s.ppc32.sr[i]);
}
for (i = 0; i < 8; i++) {
kvmppc_set_bat(vcpu, &(vcpu3s->ibat[i]), false,
(u32)sregs->u.s.ppc32.ibat[i]);
kvmppc_set_bat(vcpu, &(vcpu3s->ibat[i]), true,
(u32)(sregs->u.s.ppc32.ibat[i] >> 32));
kvmppc_set_bat(vcpu, &(vcpu3s->dbat[i]), false,
(u32)sregs->u.s.ppc32.dbat[i]);
kvmppc_set_bat(vcpu, &(vcpu3s->dbat[i]), true,
(u32)(sregs->u.s.ppc32.dbat[i] >> 32));
}
}

/* Flush the MMU after messing with the segments */
kvmppc_mmu_pte_flush(vcpu, 0, 0);
return 0;
}

Expand Down
38 changes: 23 additions & 15 deletions trunk/arch/powerpc/kvm/book3s_64_emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,27 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
return emulated;
}

static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u64 val)
void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, bool upper,
u32 val)
{
if (upper) {
/* Upper BAT */
u32 bl = (val >> 2) & 0x7ff;
bat->bepi_mask = (~bl << 17);
bat->bepi = val & 0xfffe0000;
bat->vs = (val & 2) ? 1 : 0;
bat->vp = (val & 1) ? 1 : 0;
bat->raw = (bat->raw & 0xffffffff00000000ULL) | val;
} else {
/* Lower BAT */
bat->brpn = val & 0xfffe0000;
bat->wimg = (val >> 3) & 0xf;
bat->pp = val & 3;
bat->raw = (bat->raw & 0x00000000ffffffffULL) | ((u64)val << 32);
}
}

static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u32 val)
{
struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
struct kvmppc_bat *bat;
Expand All @@ -207,19 +227,7 @@ static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u64 val)
BUG();
}

if (!(sprn % 2)) {
/* Upper BAT */
u32 bl = (val >> 2) & 0x7ff;
bat->bepi_mask = (~bl << 17);
bat->bepi = val & 0xfffe0000;
bat->vs = (val & 2) ? 1 : 0;
bat->vp = (val & 1) ? 1 : 0;
} else {
/* Lower BAT */
bat->brpn = val & 0xfffe0000;
bat->wimg = (val >> 3) & 0xf;
bat->pp = val & 3;
}
kvmppc_set_bat(vcpu, bat, !(sprn % 2), val);
}

int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
Expand All @@ -243,7 +251,7 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
case SPRN_IBAT4U ... SPRN_IBAT7L:
case SPRN_DBAT0U ... SPRN_DBAT3L:
case SPRN_DBAT4U ... SPRN_DBAT7L:
kvmppc_write_bat(vcpu, sprn, vcpu->arch.gpr[rs]);
kvmppc_write_bat(vcpu, sprn, (u32)vcpu->arch.gpr[rs]);
/* BAT writes happen so rarely that we're ok to flush
* everything here */
kvmppc_mmu_pte_flush(vcpu, 0, 0);
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/powerpc/kvm/book3s_64_mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -473,4 +473,6 @@ void kvmppc_mmu_book3s_64_init(struct kvm_vcpu *vcpu)
mmu->esid_to_vsid = kvmppc_mmu_book3s_64_esid_to_vsid;
mmu->ea_to_vp = kvmppc_mmu_book3s_64_ea_to_vp;
mmu->is_dcbz32 = kvmppc_mmu_book3s_64_is_dcbz32;

vcpu->arch.hflags |= BOOK3S_HFLAG_SLB;
}
3 changes: 3 additions & 0 deletions trunk/arch/powerpc/kvm/powerpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ int kvm_dev_ioctl_check_extension(long ext)
int r;

switch (ext) {
case KVM_CAP_PPC_SEGSTATE:
r = 1;
break;
case KVM_CAP_COALESCED_MMIO:
r = KVM_COALESCED_MMIO_PAGE_OFFSET;
break;
Expand Down
3 changes: 3 additions & 0 deletions trunk/include/linux/kvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,9 @@ struct kvm_ioeventfd {
#endif
#define KVM_CAP_IOEVENTFD 36
#define KVM_CAP_SET_IDENTITY_MAP_ADDR 37
/* KVM upstream has more features, but we synched this number.
Linux, please remove this comment on rebase. */
#define KVM_CAP_PPC_SEGSTATE 43

#ifdef KVM_CAP_IRQ_ROUTING

Expand Down

0 comments on commit 0d8665f

Please sign in to comment.