diff options
author | Alexander Graf <agraf@suse.de> | 2010-07-29 08:48:05 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-10-24 04:50:56 -0400 |
commit | 7810927760a0d16d7a41be4dab895fbbf9445bc0 (patch) | |
tree | f215dd900d26d691c05f9b48233b7ef910b4fb1d /arch/powerpc/kernel/kvm_emul.S | |
parent | 819a63dc792b0888edd3eda306a9e1e049dcbb1c (diff) |
KVM: PPC: PV mtmsrd L=0 and mtmsr
There is also a form of mtmsr where all bits need to be addressed. While the
PPC64 Linux kernel behaves resonably well here, on PPC32 we do not have an
L=1 form. It does mtmsr even for simple things like only changing EE.
So we need to hook into that one as well and check for a mask of bits that we
deem safe to change from within guest context.
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/powerpc/kernel/kvm_emul.S')
-rw-r--r-- | arch/powerpc/kernel/kvm_emul.S | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/kvm_emul.S b/arch/powerpc/kernel/kvm_emul.S index 10dc4a6632fd..8cd22f47dd01 100644 --- a/arch/powerpc/kernel/kvm_emul.S +++ b/arch/powerpc/kernel/kvm_emul.S | |||
@@ -120,3 +120,87 @@ kvm_emulate_mtmsrd_reg_offs: | |||
120 | .global kvm_emulate_mtmsrd_len | 120 | .global kvm_emulate_mtmsrd_len |
121 | kvm_emulate_mtmsrd_len: | 121 | kvm_emulate_mtmsrd_len: |
122 | .long (kvm_emulate_mtmsrd_end - kvm_emulate_mtmsrd) / 4 | 122 | .long (kvm_emulate_mtmsrd_end - kvm_emulate_mtmsrd) / 4 |
123 | |||
124 | |||
125 | #define MSR_SAFE_BITS (MSR_EE | MSR_CE | MSR_ME | MSR_RI) | ||
126 | #define MSR_CRITICAL_BITS ~MSR_SAFE_BITS | ||
127 | |||
128 | .global kvm_emulate_mtmsr | ||
129 | kvm_emulate_mtmsr: | ||
130 | |||
131 | SCRATCH_SAVE | ||
132 | |||
133 | /* Fetch old MSR in r31 */ | ||
134 | LL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0) | ||
135 | |||
136 | /* Find the changed bits between old and new MSR */ | ||
137 | kvm_emulate_mtmsr_reg1: | ||
138 | xor r31, r0, r31 | ||
139 | |||
140 | /* Check if we need to really do mtmsr */ | ||
141 | LOAD_REG_IMMEDIATE(r30, MSR_CRITICAL_BITS) | ||
142 | and. r31, r31, r30 | ||
143 | |||
144 | /* No critical bits changed? Maybe we can stay in the guest. */ | ||
145 | beq maybe_stay_in_guest | ||
146 | |||
147 | do_mtmsr: | ||
148 | |||
149 | SCRATCH_RESTORE | ||
150 | |||
151 | /* Just fire off the mtmsr if it's critical */ | ||
152 | kvm_emulate_mtmsr_orig_ins: | ||
153 | mtmsr r0 | ||
154 | |||
155 | b kvm_emulate_mtmsr_branch | ||
156 | |||
157 | maybe_stay_in_guest: | ||
158 | |||
159 | /* Check if we have to fetch an interrupt */ | ||
160 | lwz r31, (KVM_MAGIC_PAGE + KVM_MAGIC_INT)(0) | ||
161 | cmpwi r31, 0 | ||
162 | beq+ no_mtmsr | ||
163 | |||
164 | /* Check if we may trigger an interrupt */ | ||
165 | kvm_emulate_mtmsr_reg2: | ||
166 | andi. r31, r0, MSR_EE | ||
167 | beq no_mtmsr | ||
168 | |||
169 | b do_mtmsr | ||
170 | |||
171 | no_mtmsr: | ||
172 | |||
173 | /* Put MSR into magic page because we don't call mtmsr */ | ||
174 | kvm_emulate_mtmsr_reg3: | ||
175 | STL64(r0, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0) | ||
176 | |||
177 | SCRATCH_RESTORE | ||
178 | |||
179 | /* Go back to caller */ | ||
180 | kvm_emulate_mtmsr_branch: | ||
181 | b . | ||
182 | kvm_emulate_mtmsr_end: | ||
183 | |||
184 | .global kvm_emulate_mtmsr_branch_offs | ||
185 | kvm_emulate_mtmsr_branch_offs: | ||
186 | .long (kvm_emulate_mtmsr_branch - kvm_emulate_mtmsr) / 4 | ||
187 | |||
188 | .global kvm_emulate_mtmsr_reg1_offs | ||
189 | kvm_emulate_mtmsr_reg1_offs: | ||
190 | .long (kvm_emulate_mtmsr_reg1 - kvm_emulate_mtmsr) / 4 | ||
191 | |||
192 | .global kvm_emulate_mtmsr_reg2_offs | ||
193 | kvm_emulate_mtmsr_reg2_offs: | ||
194 | .long (kvm_emulate_mtmsr_reg2 - kvm_emulate_mtmsr) / 4 | ||
195 | |||
196 | .global kvm_emulate_mtmsr_reg3_offs | ||
197 | kvm_emulate_mtmsr_reg3_offs: | ||
198 | .long (kvm_emulate_mtmsr_reg3 - kvm_emulate_mtmsr) / 4 | ||
199 | |||
200 | .global kvm_emulate_mtmsr_orig_ins_offs | ||
201 | kvm_emulate_mtmsr_orig_ins_offs: | ||
202 | .long (kvm_emulate_mtmsr_orig_ins - kvm_emulate_mtmsr) / 4 | ||
203 | |||
204 | .global kvm_emulate_mtmsr_len | ||
205 | kvm_emulate_mtmsr_len: | ||
206 | .long (kvm_emulate_mtmsr_end - kvm_emulate_mtmsr) / 4 | ||