2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2, as
4 * published by the Free Software Foundation.
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 * Copyright IBM Corp. 2008
17 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
20 #include <linux/kvm_host.h>
22 #include <asm/cputable.h>
23 #include <asm/tlbflush.h>
27 /* Note: clearing MSR[DE] just means that the debug interrupt will not be
28 * delivered *immediately*. Instead, it simply sets the appropriate DBSR bits.
29 * If those DBSR bits are still set when MSR[DE] is re-enabled, the interrupt
30 * will be delivered as an "imprecise debug event" (which is indicated by
33 static void kvm44x_disable_debug_interrupts(void)
35 mtmsr(mfmsr() & ~MSR_DE
);
38 void kvmppc_core_load_host_debugstate(struct kvm_vcpu
*vcpu
)
40 kvm44x_disable_debug_interrupts();
42 mtspr(SPRN_IAC1
, vcpu
->arch
.host_iac
[0]);
43 mtspr(SPRN_IAC2
, vcpu
->arch
.host_iac
[1]);
44 mtspr(SPRN_IAC3
, vcpu
->arch
.host_iac
[2]);
45 mtspr(SPRN_IAC4
, vcpu
->arch
.host_iac
[3]);
46 mtspr(SPRN_DBCR1
, vcpu
->arch
.host_dbcr1
);
47 mtspr(SPRN_DBCR2
, vcpu
->arch
.host_dbcr2
);
48 mtspr(SPRN_DBCR0
, vcpu
->arch
.host_dbcr0
);
49 mtmsr(vcpu
->arch
.host_msr
);
52 void kvmppc_core_load_guest_debugstate(struct kvm_vcpu
*vcpu
)
54 struct kvm_guest_debug
*dbg
= &vcpu
->guest_debug
;
57 vcpu
->arch
.host_msr
= mfmsr();
58 kvm44x_disable_debug_interrupts();
60 /* Save host debug register state. */
61 vcpu
->arch
.host_iac
[0] = mfspr(SPRN_IAC1
);
62 vcpu
->arch
.host_iac
[1] = mfspr(SPRN_IAC2
);
63 vcpu
->arch
.host_iac
[2] = mfspr(SPRN_IAC3
);
64 vcpu
->arch
.host_iac
[3] = mfspr(SPRN_IAC4
);
65 vcpu
->arch
.host_dbcr0
= mfspr(SPRN_DBCR0
);
66 vcpu
->arch
.host_dbcr1
= mfspr(SPRN_DBCR1
);
67 vcpu
->arch
.host_dbcr2
= mfspr(SPRN_DBCR2
);
69 /* set registers up for guest */
72 mtspr(SPRN_IAC1
, dbg
->bp
[0]);
73 dbcr0
|= DBCR0_IAC1
| DBCR0_IDM
;
76 mtspr(SPRN_IAC2
, dbg
->bp
[1]);
77 dbcr0
|= DBCR0_IAC2
| DBCR0_IDM
;
80 mtspr(SPRN_IAC3
, dbg
->bp
[2]);
81 dbcr0
|= DBCR0_IAC3
| DBCR0_IDM
;
84 mtspr(SPRN_IAC4
, dbg
->bp
[3]);
85 dbcr0
|= DBCR0_IAC4
| DBCR0_IDM
;
88 mtspr(SPRN_DBCR0
, dbcr0
);
93 void kvmppc_core_vcpu_load(struct kvm_vcpu
*vcpu
, int cpu
)
97 /* Mark every guest entry in the shadow TLB entry modified, so that they
98 * will all be reloaded on the next vcpu run (instead of being
100 for (i
= 0; i
<= tlb_44x_hwater
; i
++)
101 kvmppc_tlbe_set_modified(vcpu
, i
);
104 void kvmppc_core_vcpu_put(struct kvm_vcpu
*vcpu
)
106 /* Don't leave guest TLB entries resident when being de-scheduled. */
107 /* XXX It would be nice to differentiate between heavyweight exit and
108 * sched_out here, since we could avoid the TLB flush for heavyweight
113 int kvmppc_core_check_processor_compat(void)
117 if (strcmp(cur_cpu_spec
->platform
, "ppc440") == 0)
125 int kvmppc_core_vcpu_setup(struct kvm_vcpu
*vcpu
)
127 struct kvmppc_44x_tlbe
*tlbe
= &vcpu
->arch
.guest_tlb
[0];
130 tlbe
->word0
= PPC44x_TLB_16M
| PPC44x_TLB_VALID
;
132 tlbe
->word2
= PPC44x_TLB_SX
| PPC44x_TLB_SW
| PPC44x_TLB_SR
;
136 tlbe
->word0
= 0xef600000 | PPC44x_TLB_4K
| PPC44x_TLB_VALID
;
137 tlbe
->word1
= 0xef600000;
138 tlbe
->word2
= PPC44x_TLB_SX
| PPC44x_TLB_SW
| PPC44x_TLB_SR
139 | PPC44x_TLB_I
| PPC44x_TLB_G
;
141 /* Since the guest can directly access the timebase, it must know the
142 * real timebase frequency. Accordingly, it must see the state of
144 vcpu
->arch
.ccr1
= mfspr(SPRN_CCR1
);
149 /* 'linear_address' is actually an encoding of AS|PID|EADDR . */
150 int kvmppc_core_vcpu_translate(struct kvm_vcpu
*vcpu
,
151 struct kvm_translation
*tr
)
153 struct kvmppc_44x_tlbe
*gtlbe
;
159 eaddr
= tr
->linear_address
;
160 pid
= (tr
->linear_address
>> 32) & 0xff;
161 as
= (tr
->linear_address
>> 40) & 0x1;
163 index
= kvmppc_44x_tlb_index(vcpu
, eaddr
, pid
, as
);
169 gtlbe
= &vcpu
->arch
.guest_tlb
[index
];
171 tr
->physical_address
= tlb_xlate(gtlbe
, eaddr
);
172 /* XXX what does "writeable" and "usermode" even mean? */