aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2011-04-27 18:24:21 -0400
committerAvi Kivity <avi@redhat.com>2011-05-22 08:47:53 -0400
commit5ce941ee4258b836cf818d2ac159d8cf3ebad648 (patch)
tree082526b38824e8f763944c39a7e0e9390f298882
parenteab176722f4628b2d9cf76221a43dd3a0e37e632 (diff)
KVM: PPC: booke: add sregs support
Signed-off-by: Scott Wood <scottwood@freescale.com> Signed-off-by: Alexander Graf <agraf@suse.de>
-rw-r--r--Documentation/kvm/api.txt6
-rw-r--r--arch/powerpc/include/asm/kvm.h184
-rw-r--r--arch/powerpc/include/asm/kvm_44x.h1
-rw-r--r--arch/powerpc/include/asm/kvm_e500.h1
-rw-r--r--arch/powerpc/include/asm/kvm_host.h3
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h9
-rw-r--r--arch/powerpc/kvm/44x.c10
-rw-r--r--arch/powerpc/kvm/booke.c154
-rw-r--r--arch/powerpc/kvm/e500.c75
-rw-r--r--arch/powerpc/kvm/e500_emulate.c5
-rw-r--r--arch/powerpc/kvm/e500_tlb.c8
-rw-r--r--arch/powerpc/kvm/emulate.c13
-rw-r--r--arch/powerpc/kvm/powerpc.c4
-rw-r--r--include/linux/kvm.h1
14 files changed, 461 insertions, 13 deletions
diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt
index 1b9eaa7e8856..f64c41f8ba61 100644
--- a/Documentation/kvm/api.txt
+++ b/Documentation/kvm/api.txt
@@ -261,7 +261,7 @@ See KVM_GET_REGS for the data structure.
2614.13 KVM_GET_SREGS 2614.13 KVM_GET_SREGS
262 262
263Capability: basic 263Capability: basic
264Architectures: x86 264Architectures: x86, ppc
265Type: vcpu ioctl 265Type: vcpu ioctl
266Parameters: struct kvm_sregs (out) 266Parameters: struct kvm_sregs (out)
267Returns: 0 on success, -1 on error 267Returns: 0 on success, -1 on error
@@ -279,6 +279,8 @@ struct kvm_sregs {
279 __u64 interrupt_bitmap[(KVM_NR_INTERRUPTS + 63) / 64]; 279 __u64 interrupt_bitmap[(KVM_NR_INTERRUPTS + 63) / 64];
280}; 280};
281 281
282/* ppc -- see arch/powerpc/include/asm/kvm.h */
283
282interrupt_bitmap is a bitmap of pending external interrupts. At most 284interrupt_bitmap is a bitmap of pending external interrupts. At most
283one bit may be set. This interrupt has been acknowledged by the APIC 285one bit may be set. This interrupt has been acknowledged by the APIC
284but not yet injected into the cpu core. 286but not yet injected into the cpu core.
@@ -286,7 +288,7 @@ but not yet injected into the cpu core.
2864.14 KVM_SET_SREGS 2884.14 KVM_SET_SREGS
287 289
288Capability: basic 290Capability: basic
289Architectures: x86 291Architectures: x86, ppc
290Type: vcpu ioctl 292Type: vcpu ioctl
291Parameters: struct kvm_sregs (in) 293Parameters: struct kvm_sregs (in)
292Returns: 0 on success, -1 on error 294Returns: 0 on success, -1 on error
diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h
index 18ea6963ad77..d2ca5ed3877b 100644
--- a/arch/powerpc/include/asm/kvm.h
+++ b/arch/powerpc/include/asm/kvm.h
@@ -45,6 +45,114 @@ struct kvm_regs {
45 __u64 gpr[32]; 45 __u64 gpr[32];
46}; 46};
47 47
48#define KVM_SREGS_E_IMPL_NONE 0
49#define KVM_SREGS_E_IMPL_FSL 1
50
51#define KVM_SREGS_E_FSL_PIDn (1 << 0) /* PID1/PID2 */
52
53/*
54 * Feature bits indicate which sections of the sregs struct are valid,
55 * both in KVM_GET_SREGS and KVM_SET_SREGS. On KVM_SET_SREGS, registers
56 * corresponding to unset feature bits will not be modified. This allows
57 * restoring a checkpoint made without that feature, while keeping the
58 * default values of the new registers.
59 *
60 * KVM_SREGS_E_BASE contains:
61 * CSRR0/1 (refers to SRR2/3 on 40x)
62 * ESR
63 * DEAR
64 * MCSR
65 * TSR
66 * TCR
67 * DEC
68 * TB
69 * VRSAVE (USPRG0)
70 */
71#define KVM_SREGS_E_BASE (1 << 0)
72
73/*
74 * KVM_SREGS_E_ARCH206 contains:
75 *
76 * PIR
77 * MCSRR0/1
78 * DECAR
79 * IVPR
80 */
81#define KVM_SREGS_E_ARCH206 (1 << 1)
82
83/*
84 * Contains EPCR, plus the upper half of 64-bit registers
85 * that are 32-bit on 32-bit implementations.
86 */
87#define KVM_SREGS_E_64 (1 << 2)
88
89#define KVM_SREGS_E_SPRG8 (1 << 3)
90#define KVM_SREGS_E_MCIVPR (1 << 4)
91
92/*
93 * IVORs are used -- contains IVOR0-15, plus additional IVORs
94 * in combination with an appropriate feature bit.
95 */
96#define KVM_SREGS_E_IVOR (1 << 5)
97
98/*
99 * Contains MAS0-4, MAS6-7, TLBnCFG, MMUCFG.
100 * Also TLBnPS if MMUCFG[MAVN] = 1.
101 */
102#define KVM_SREGS_E_ARCH206_MMU (1 << 6)
103
104/* DBSR, DBCR, IAC, DAC, DVC */
105#define KVM_SREGS_E_DEBUG (1 << 7)
106
107/* Enhanced debug -- DSRR0/1, SPRG9 */
108#define KVM_SREGS_E_ED (1 << 8)
109
110/* Embedded Floating Point (SPE) -- IVOR32-34 if KVM_SREGS_E_IVOR */
111#define KVM_SREGS_E_SPE (1 << 9)
112
113/* External Proxy (EXP) -- EPR */
114#define KVM_SREGS_EXP (1 << 10)
115
116/* External PID (E.PD) -- EPSC/EPLC */
117#define KVM_SREGS_E_PD (1 << 11)
118
119/* Processor Control (E.PC) -- IVOR36-37 if KVM_SREGS_E_IVOR */
120#define KVM_SREGS_E_PC (1 << 12)
121
122/* Page table (E.PT) -- EPTCFG */
123#define KVM_SREGS_E_PT (1 << 13)
124
125/* Embedded Performance Monitor (E.PM) -- IVOR35 if KVM_SREGS_E_IVOR */
126#define KVM_SREGS_E_PM (1 << 14)
127
128/*
129 * Special updates:
130 *
131 * Some registers may change even while a vcpu is not running.
132 * To avoid losing these changes, by default these registers are
133 * not updated by KVM_SET_SREGS. To force an update, set the bit
134 * in u.e.update_special corresponding to the register to be updated.
135 *
136 * The update_special field is zero on return from KVM_GET_SREGS.
137 *
138 * When restoring a checkpoint, the caller can set update_special
139 * to 0xffffffff to ensure that everything is restored, even new features
140 * that the caller doesn't know about.
141 */
142#define KVM_SREGS_E_UPDATE_MCSR (1 << 0)
143#define KVM_SREGS_E_UPDATE_TSR (1 << 1)
144#define KVM_SREGS_E_UPDATE_DEC (1 << 2)
145#define KVM_SREGS_E_UPDATE_DBSR (1 << 3)
146
147/*
148 * In KVM_SET_SREGS, reserved/pad fields must be left untouched from a
149 * previous KVM_GET_REGS.
150 *
151 * Unless otherwise indicated, setting any register with KVM_SET_SREGS
152 * directly sets its value. It does not trigger any special semantics such
153 * as write-one-to-clear. Calling KVM_SET_SREGS on an unmodified struct
154 * just received from KVM_GET_SREGS is always a no-op.
155 */
48struct kvm_sregs { 156struct kvm_sregs {
49 __u32 pvr; 157 __u32 pvr;
50 union { 158 union {
@@ -62,6 +170,82 @@ struct kvm_sregs {
62 __u64 dbat[8]; 170 __u64 dbat[8];
63 } ppc32; 171 } ppc32;
64 } s; 172 } s;
173 struct {
174 union {
175 struct { /* KVM_SREGS_E_IMPL_FSL */
176 __u32 features; /* KVM_SREGS_E_FSL_ */
177 __u32 svr;
178 __u64 mcar;
179 __u32 hid0;
180
181 /* KVM_SREGS_E_FSL_PIDn */
182 __u32 pid1, pid2;
183 } fsl;
184 __u8 pad[256];
185 } impl;
186
187 __u32 features; /* KVM_SREGS_E_ */
188 __u32 impl_id; /* KVM_SREGS_E_IMPL_ */
189 __u32 update_special; /* KVM_SREGS_E_UPDATE_ */
190 __u32 pir; /* read-only */
191 __u64 sprg8;
192 __u64 sprg9; /* E.ED */
193 __u64 csrr0;
194 __u64 dsrr0; /* E.ED */
195 __u64 mcsrr0;
196 __u32 csrr1;
197 __u32 dsrr1; /* E.ED */
198 __u32 mcsrr1;
199 __u32 esr;
200 __u64 dear;
201 __u64 ivpr;
202 __u64 mcivpr;
203 __u64 mcsr; /* KVM_SREGS_E_UPDATE_MCSR */
204
205 __u32 tsr; /* KVM_SREGS_E_UPDATE_TSR */
206 __u32 tcr;
207 __u32 decar;
208 __u32 dec; /* KVM_SREGS_E_UPDATE_DEC */
209
210 /*
211 * Userspace can read TB directly, but the
212 * value reported here is consistent with "dec".
213 *
214 * Read-only.
215 */
216 __u64 tb;
217
218 __u32 dbsr; /* KVM_SREGS_E_UPDATE_DBSR */
219 __u32 dbcr[3];
220 __u32 iac[4];
221 __u32 dac[2];
222 __u32 dvc[2];
223 __u8 num_iac; /* read-only */
224 __u8 num_dac; /* read-only */
225 __u8 num_dvc; /* read-only */
226 __u8 pad;
227
228 __u32 epr; /* EXP */
229 __u32 vrsave; /* a.k.a. USPRG0 */
230 __u32 epcr; /* KVM_SREGS_E_64 */
231
232 __u32 mas0;
233 __u32 mas1;
234 __u64 mas2;
235 __u64 mas7_3;
236 __u32 mas4;
237 __u32 mas6;
238
239 __u32 ivor_low[16]; /* IVOR0-15 */
240 __u32 ivor_high[18]; /* IVOR32+, plus room to expand */
241
242 __u32 mmucfg; /* read-only */
243 __u32 eptcfg; /* E.PT, read-only */
244 __u32 tlbcfg[4];/* read-only */
245 __u32 tlbps[4]; /* read-only */
246
247 __u32 eplc, epsc; /* E.PD */
248 } e;
65 __u8 pad[1020]; 249 __u8 pad[1020];
66 } u; 250 } u;
67}; 251};
diff --git a/arch/powerpc/include/asm/kvm_44x.h b/arch/powerpc/include/asm/kvm_44x.h
index d22d39942a92..a0e57618ff33 100644
--- a/arch/powerpc/include/asm/kvm_44x.h
+++ b/arch/powerpc/include/asm/kvm_44x.h
@@ -61,7 +61,6 @@ static inline struct kvmppc_vcpu_44x *to_44x(struct kvm_vcpu *vcpu)
61 return container_of(vcpu, struct kvmppc_vcpu_44x, vcpu); 61 return container_of(vcpu, struct kvmppc_vcpu_44x, vcpu);
62} 62}
63 63
64void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 new_pid);
65void kvmppc_44x_tlb_put(struct kvm_vcpu *vcpu); 64void kvmppc_44x_tlb_put(struct kvm_vcpu *vcpu);
66void kvmppc_44x_tlb_load(struct kvm_vcpu *vcpu); 65void kvmppc_44x_tlb_load(struct kvm_vcpu *vcpu);
67 66
diff --git a/arch/powerpc/include/asm/kvm_e500.h b/arch/powerpc/include/asm/kvm_e500.h
index bb2a0890600f..7a2a565f88c4 100644
--- a/arch/powerpc/include/asm/kvm_e500.h
+++ b/arch/powerpc/include/asm/kvm_e500.h
@@ -59,6 +59,7 @@ struct kvmppc_vcpu_e500 {
59 u32 hid1; 59 u32 hid1;
60 u32 tlb0cfg; 60 u32 tlb0cfg;
61 u32 tlb1cfg; 61 u32 tlb1cfg;
62 u64 mcar;
62 63
63 struct kvm_vcpu vcpu; 64 struct kvm_vcpu vcpu;
64}; 65};
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index a16804399165..186f150b9b89 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -233,6 +233,9 @@ struct kvm_vcpu_arch {
233 ulong csrr1; 233 ulong csrr1;
234 ulong dsrr0; 234 ulong dsrr0;
235 ulong dsrr1; 235 ulong dsrr1;
236 ulong mcsrr0;
237 ulong mcsrr1;
238 ulong mcsr;
236 ulong esr; 239 ulong esr;
237 u32 dec; 240 u32 dec;
238 u32 decar; 241 u32 decar;
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index ecb3bc74c344..9345238edecf 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -61,6 +61,7 @@ extern int kvmppc_emulate_instruction(struct kvm_run *run,
61 struct kvm_vcpu *vcpu); 61 struct kvm_vcpu *vcpu);
62extern int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu); 62extern int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu);
63extern void kvmppc_emulate_dec(struct kvm_vcpu *vcpu); 63extern void kvmppc_emulate_dec(struct kvm_vcpu *vcpu);
64extern u32 kvmppc_get_dec(struct kvm_vcpu *vcpu, u64 tb);
64 65
65/* Core-specific hooks */ 66/* Core-specific hooks */
66 67
@@ -142,4 +143,12 @@ static inline u32 kvmppc_set_field(u64 inst, int msb, int lsb, int value)
142 return r; 143 return r;
143} 144}
144 145
146void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
147int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
148
149void kvmppc_get_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
150int kvmppc_set_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
151
152void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid);
153
145#endif /* __POWERPC_KVM_PPC_H__ */ 154#endif /* __POWERPC_KVM_PPC_H__ */
diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c
index 74d0e7421143..da3a1225c0ac 100644
--- a/arch/powerpc/kvm/44x.c
+++ b/arch/powerpc/kvm/44x.c
@@ -107,6 +107,16 @@ int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
107 return 0; 107 return 0;
108} 108}
109 109
110void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
111{
112 kvmppc_get_sregs_ivor(vcpu, sregs);
113}
114
115int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
116{
117 return kvmppc_set_sregs_ivor(vcpu, sregs);
118}
119
110struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) 120struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
111{ 121{
112 struct kvmppc_vcpu_44x *vcpu_44x; 122 struct kvmppc_vcpu_44x *vcpu_44x;
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index ef76acb455c3..8462b3a1c1c7 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -569,6 +569,7 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
569 kvmppc_set_msr(vcpu, regs->msr); 569 kvmppc_set_msr(vcpu, regs->msr);
570 vcpu->arch.shared->srr0 = regs->srr0; 570 vcpu->arch.shared->srr0 = regs->srr0;
571 vcpu->arch.shared->srr1 = regs->srr1; 571 vcpu->arch.shared->srr1 = regs->srr1;
572 kvmppc_set_pid(vcpu, regs->pid);
572 vcpu->arch.shared->sprg0 = regs->sprg0; 573 vcpu->arch.shared->sprg0 = regs->sprg0;
573 vcpu->arch.shared->sprg1 = regs->sprg1; 574 vcpu->arch.shared->sprg1 = regs->sprg1;
574 vcpu->arch.shared->sprg2 = regs->sprg2; 575 vcpu->arch.shared->sprg2 = regs->sprg2;
@@ -584,16 +585,165 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
584 return 0; 585 return 0;
585} 586}
586 587
588static void get_sregs_base(struct kvm_vcpu *vcpu,
589 struct kvm_sregs *sregs)
590{
591 u64 tb = get_tb();
592
593 sregs->u.e.features |= KVM_SREGS_E_BASE;
594
595 sregs->u.e.csrr0 = vcpu->arch.csrr0;
596 sregs->u.e.csrr1 = vcpu->arch.csrr1;
597 sregs->u.e.mcsr = vcpu->arch.mcsr;
598 sregs->u.e.esr = vcpu->arch.esr;
599 sregs->u.e.dear = vcpu->arch.shared->dar;
600 sregs->u.e.tsr = vcpu->arch.tsr;
601 sregs->u.e.tcr = vcpu->arch.tcr;
602 sregs->u.e.dec = kvmppc_get_dec(vcpu, tb);
603 sregs->u.e.tb = tb;
604 sregs->u.e.vrsave = vcpu->arch.vrsave;
605}
606
607static int set_sregs_base(struct kvm_vcpu *vcpu,
608 struct kvm_sregs *sregs)
609{
610 if (!(sregs->u.e.features & KVM_SREGS_E_BASE))
611 return 0;
612
613 vcpu->arch.csrr0 = sregs->u.e.csrr0;
614 vcpu->arch.csrr1 = sregs->u.e.csrr1;
615 vcpu->arch.mcsr = sregs->u.e.mcsr;
616 vcpu->arch.esr = sregs->u.e.esr;
617 vcpu->arch.shared->dar = sregs->u.e.dear;
618 vcpu->arch.vrsave = sregs->u.e.vrsave;
619 vcpu->arch.tcr = sregs->u.e.tcr;
620
621 if (sregs->u.e.update_special & KVM_SREGS_E_UPDATE_DEC)
622 vcpu->arch.dec = sregs->u.e.dec;
623
624 kvmppc_emulate_dec(vcpu);
625
626 if (sregs->u.e.update_special & KVM_SREGS_E_UPDATE_TSR) {
627 /*
628 * FIXME: existing KVM timer handling is incomplete.
629 * TSR cannot be read by the guest, and its value in
630 * vcpu->arch is always zero. For now, just handle
631 * the case where the caller is trying to inject a
632 * decrementer interrupt.
633 */
634
635 if ((sregs->u.e.tsr & TSR_DIS) &&
636 (vcpu->arch.tcr & TCR_DIE))
637 kvmppc_core_queue_dec(vcpu);
638 }
639
640 return 0;
641}
642
643static void get_sregs_arch206(struct kvm_vcpu *vcpu,
644 struct kvm_sregs *sregs)
645{
646 sregs->u.e.features |= KVM_SREGS_E_ARCH206;
647
648 sregs->u.e.pir = 0;
649 sregs->u.e.mcsrr0 = vcpu->arch.mcsrr0;
650 sregs->u.e.mcsrr1 = vcpu->arch.mcsrr1;
651 sregs->u.e.decar = vcpu->arch.decar;
652 sregs->u.e.ivpr = vcpu->arch.ivpr;
653}
654
655static int set_sregs_arch206(struct kvm_vcpu *vcpu,
656 struct kvm_sregs *sregs)
657{
658 if (!(sregs->u.e.features & KVM_SREGS_E_ARCH206))
659 return 0;
660
661 if (sregs->u.e.pir != 0)
662 return -EINVAL;
663
664 vcpu->arch.mcsrr0 = sregs->u.e.mcsrr0;
665 vcpu->arch.mcsrr1 = sregs->u.e.mcsrr1;
666 vcpu->arch.decar = sregs->u.e.decar;
667 vcpu->arch.ivpr = sregs->u.e.ivpr;
668
669 return 0;
670}
671
672void kvmppc_get_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
673{
674 sregs->u.e.features |= KVM_SREGS_E_IVOR;
675
676 sregs->u.e.ivor_low[0] = vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL];
677 sregs->u.e.ivor_low[1] = vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK];
678 sregs->u.e.ivor_low[2] = vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE];
679 sregs->u.e.ivor_low[3] = vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE];
680 sregs->u.e.ivor_low[4] = vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL];
681 sregs->u.e.ivor_low[5] = vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT];
682 sregs->u.e.ivor_low[6] = vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM];
683 sregs->u.e.ivor_low[7] = vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL];
684 sregs->u.e.ivor_low[8] = vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL];
685 sregs->u.e.ivor_low[9] = vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL];
686 sregs->u.e.ivor_low[10] = vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER];
687 sregs->u.e.ivor_low[11] = vcpu->arch.ivor[BOOKE_IRQPRIO_FIT];
688 sregs->u.e.ivor_low[12] = vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG];
689 sregs->u.e.ivor_low[13] = vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS];
690 sregs->u.e.ivor_low[14] = vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS];
691 sregs->u.e.ivor_low[15] = vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG];
692}
693
694int kvmppc_set_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
695{
696 if (!(sregs->u.e.features & KVM_SREGS_E_IVOR))
697 return 0;
698
699 vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = sregs->u.e.ivor_low[0];
700 vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK] = sregs->u.e.ivor_low[1];
701 vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = sregs->u.e.ivor_low[2];
702 vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = sregs->u.e.ivor_low[3];
703 vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL] = sregs->u.e.ivor_low[4];
704 vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT] = sregs->u.e.ivor_low[5];
705 vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM] = sregs->u.e.ivor_low[6];
706 vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL] = sregs->u.e.ivor_low[7];
707 vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = sregs->u.e.ivor_low[8];
708 vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = sregs->u.e.ivor_low[9];
709 vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER] = sregs->u.e.ivor_low[10];
710 vcpu->arch.ivor[BOOKE_IRQPRIO_FIT] = sregs->u.e.ivor_low[11];
711 vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG] = sregs->u.e.ivor_low[12];
712 vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS] = sregs->u.e.ivor_low[13];
713 vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS] = sregs->u.e.ivor_low[14];
714 vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG] = sregs->u.e.ivor_low[15];
715
716 return 0;
717}
718
587int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, 719int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
588 struct kvm_sregs *sregs) 720 struct kvm_sregs *sregs)
589{ 721{
590 return -ENOTSUPP; 722 sregs->pvr = vcpu->arch.pvr;
723
724 get_sregs_base(vcpu, sregs);
725 get_sregs_arch206(vcpu, sregs);
726 kvmppc_core_get_sregs(vcpu, sregs);
727 return 0;
591} 728}
592 729
593int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, 730int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
594 struct kvm_sregs *sregs) 731 struct kvm_sregs *sregs)
595{ 732{
596 return -ENOTSUPP; 733 int ret;
734
735 if (vcpu->arch.pvr != sregs->pvr)
736 return -EINVAL;
737
738 ret = set_sregs_base(vcpu, sregs);
739 if (ret < 0)
740 return ret;
741
742 ret = set_sregs_arch206(vcpu, sregs);
743 if (ret < 0)
744 return ret;
745
746 return kvmppc_core_set_sregs(vcpu, sregs);
597} 747}
598 748
599int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) 749int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index 0c1af1267843..318dbc61ba44 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -97,6 +97,81 @@ int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
97 return 0; 97 return 0;
98} 98}
99 99
100void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
101{
102 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
103
104 sregs->u.e.features |= KVM_SREGS_E_ARCH206_MMU | KVM_SREGS_E_SPE |
105 KVM_SREGS_E_PM;
106 sregs->u.e.impl_id = KVM_SREGS_E_IMPL_FSL;
107
108 sregs->u.e.impl.fsl.features = 0;
109 sregs->u.e.impl.fsl.svr = vcpu_e500->svr;
110 sregs->u.e.impl.fsl.hid0 = vcpu_e500->hid0;
111 sregs->u.e.impl.fsl.mcar = vcpu_e500->mcar;
112
113 sregs->u.e.mas0 = vcpu_e500->mas0;
114 sregs->u.e.mas1 = vcpu_e500->mas1;
115 sregs->u.e.mas2 = vcpu_e500->mas2;
116 sregs->u.e.mas7_3 = ((u64)vcpu_e500->mas7 << 32) | vcpu_e500->mas3;
117 sregs->u.e.mas4 = vcpu_e500->mas4;
118 sregs->u.e.mas6 = vcpu_e500->mas6;
119
120 sregs->u.e.mmucfg = mfspr(SPRN_MMUCFG);
121 sregs->u.e.tlbcfg[0] = vcpu_e500->tlb0cfg;
122 sregs->u.e.tlbcfg[1] = vcpu_e500->tlb1cfg;
123 sregs->u.e.tlbcfg[2] = 0;
124 sregs->u.e.tlbcfg[3] = 0;
125
126 sregs->u.e.ivor_high[0] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL];
127 sregs->u.e.ivor_high[1] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA];
128 sregs->u.e.ivor_high[2] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND];
129 sregs->u.e.ivor_high[3] =
130 vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR];
131
132 kvmppc_get_sregs_ivor(vcpu, sregs);
133}
134
135int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
136{
137 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
138
139 if (sregs->u.e.impl_id == KVM_SREGS_E_IMPL_FSL) {
140 vcpu_e500->svr = sregs->u.e.impl.fsl.svr;
141 vcpu_e500->hid0 = sregs->u.e.impl.fsl.hid0;
142 vcpu_e500->mcar = sregs->u.e.impl.fsl.mcar;
143 }
144
145 if (sregs->u.e.features & KVM_SREGS_E_ARCH206_MMU) {
146 vcpu_e500->mas0 = sregs->u.e.mas0;
147 vcpu_e500->mas1 = sregs->u.e.mas1;
148 vcpu_e500->mas2 = sregs->u.e.mas2;
149 vcpu_e500->mas7 = sregs->u.e.mas7_3 >> 32;
150 vcpu_e500->mas3 = (u32)sregs->u.e.mas7_3;
151 vcpu_e500->mas4 = sregs->u.e.mas4;
152 vcpu_e500->mas6 = sregs->u.e.mas6;
153 }
154
155 if (!(sregs->u.e.features & KVM_SREGS_E_IVOR))
156 return 0;
157
158 if (sregs->u.e.features & KVM_SREGS_E_SPE) {
159 vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] =
160 sregs->u.e.ivor_high[0];
161 vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] =
162 sregs->u.e.ivor_high[1];
163 vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] =
164 sregs->u.e.ivor_high[2];
165 }
166
167 if (sregs->u.e.features & KVM_SREGS_E_PM) {
168 vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] =
169 sregs->u.e.ivor_high[3];
170 }
171
172 return kvmppc_set_sregs_ivor(vcpu, sregs);
173}
174
100struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) 175struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
101{ 176{
102 struct kvmppc_vcpu_e500 *vcpu_e500; 177 struct kvmppc_vcpu_e500 *vcpu_e500;
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index e2fb47f035a5..69cd665a0caf 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved. 2 * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved.
3 * 3 *
4 * Author: Yu Liu, <yu.liu@freescale.com> 4 * Author: Yu Liu, <yu.liu@freescale.com>
5 * 5 *
@@ -78,8 +78,7 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
78 78
79 switch (sprn) { 79 switch (sprn) {
80 case SPRN_PID: 80 case SPRN_PID:
81 vcpu_e500->pid[0] = vcpu->arch.shadow_pid = 81 kvmppc_set_pid(vcpu, spr_val);
82 vcpu->arch.pid = spr_val;
83 break; 82 break;
84 case SPRN_PID1: 83 case SPRN_PID1:
85 vcpu_e500->pid[1] = spr_val; break; 84 vcpu_e500->pid[1] = spr_val; break;
diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c
index 56ac4523857d..b18fe353397d 100644
--- a/arch/powerpc/kvm/e500_tlb.c
+++ b/arch/powerpc/kvm/e500_tlb.c
@@ -675,6 +675,14 @@ int kvmppc_e500_tlb_search(struct kvm_vcpu *vcpu,
675 return -1; 675 return -1;
676} 676}
677 677
678void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid)
679{
680 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
681
682 vcpu_e500->pid[0] = vcpu->arch.shadow_pid =
683 vcpu->arch.pid = pid;
684}
685
678void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *vcpu_e500) 686void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *vcpu_e500)
679{ 687{
680 struct tlbe *tlbe; 688 struct tlbe *tlbe;
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
index 8f7a3aa03c26..141dce3c6810 100644
--- a/arch/powerpc/kvm/emulate.c
+++ b/arch/powerpc/kvm/emulate.c
@@ -114,6 +114,12 @@ void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
114 } 114 }
115} 115}
116 116
117u32 kvmppc_get_dec(struct kvm_vcpu *vcpu, u64 tb)
118{
119 u64 jd = tb - vcpu->arch.dec_jiffies;
120 return vcpu->arch.dec - jd;
121}
122
117/* XXX to do: 123/* XXX to do:
118 * lhax 124 * lhax
119 * lhaux 125 * lhaux
@@ -279,11 +285,8 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
279 285
280 case SPRN_DEC: 286 case SPRN_DEC:
281 { 287 {
282 u64 jd = get_tb() - vcpu->arch.dec_jiffies; 288 kvmppc_set_gpr(vcpu, rt,
283 kvmppc_set_gpr(vcpu, rt, vcpu->arch.dec - jd); 289 kvmppc_get_dec(vcpu, get_tb()));
284 pr_debug("mfDEC: %x - %llx = %lx\n",
285 vcpu->arch.dec, jd,
286 kvmppc_get_gpr(vcpu, rt));
287 break; 290 break;
288 } 291 }
289 default: 292 default:
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 9e6aa8bfd160..616dd516ca1f 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -175,7 +175,11 @@ int kvm_dev_ioctl_check_extension(long ext)
175 int r; 175 int r;
176 176
177 switch (ext) { 177 switch (ext) {
178#ifdef CONFIG_BOOKE
179 case KVM_CAP_PPC_BOOKE_SREGS:
180#else
178 case KVM_CAP_PPC_SEGSTATE: 181 case KVM_CAP_PPC_SEGSTATE:
182#endif
179 case KVM_CAP_PPC_PAIRED_SINGLES: 183 case KVM_CAP_PPC_PAIRED_SINGLES:
180 case KVM_CAP_PPC_UNSET_IRQ: 184 case KVM_CAP_PPC_UNSET_IRQ:
181 case KVM_CAP_PPC_IRQ_LEVEL: 185 case KVM_CAP_PPC_IRQ_LEVEL:
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 2f63ebeac639..55ef181521ff 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -543,6 +543,7 @@ struct kvm_ppc_pvinfo {
543#define KVM_CAP_ASYNC_PF 59 543#define KVM_CAP_ASYNC_PF 59
544#define KVM_CAP_TSC_CONTROL 60 544#define KVM_CAP_TSC_CONTROL 60
545#define KVM_CAP_GET_TSC_KHZ 61 545#define KVM_CAP_GET_TSC_KHZ 61
546#define KVM_CAP_PPC_BOOKE_SREGS 62
546 547
547#ifdef KVM_CAP_IRQ_ROUTING 548#ifdef KVM_CAP_IRQ_ROUTING
548 549