source: trunk/packages/xen-3.1/xen-3.1/xen/arch/ia64/vmx/vmx_interrupt.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

File size: 8.6 KB
Line 
1/* -*-  Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
2/*
3 * vmx_interrupt.c: handle inject interruption.
4 * Copyright (c) 2005, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17 * Place - Suite 330, Boston, MA 02111-1307 USA.
18 *
19 *  Shaofan Li (Susue Li) <susie.li@intel.com>
20 *  Xiaoyan Feng (Fleming Feng)  <fleming.feng@intel.com>
21 *  Xuefei Xu (Anthony Xu) (Anthony.xu@intel.com)
22 */
23#include <xen/types.h>
24#include <asm/vmx_vcpu.h>
25#include <asm/vmx_mm_def.h>
26#include <asm/vmx_pal_vsa.h>
27
28/* SDM vol2 5.5 - IVA based interruption handling */
29#define INITIAL_PSR_VALUE_AT_INTERRUPTION 0x0000001808028034
30
31static void
32collect_interruption(VCPU *vcpu)
33{
34    u64 ipsr;
35    u64 vdcr;
36    u64 vifs;
37    IA64_PSR vpsr;
38    REGS * regs = vcpu_regs(vcpu);
39    vpsr.val = vmx_vcpu_get_psr(vcpu);
40    vcpu_bsw0(vcpu);
41    if(vpsr.ic){
42
43        /* Sync mpsr id/da/dd/ss/ed bits to vipsr
44         * since after guest do rfi, we still want these bits on in
45         * mpsr
46         */
47
48        ipsr = regs->cr_ipsr;
49        vpsr.val = vpsr.val | (ipsr & (IA64_PSR_ID | IA64_PSR_DA
50             | IA64_PSR_DD |IA64_PSR_SS |IA64_PSR_ED));
51        vcpu_set_ipsr(vcpu, vpsr.val);
52
53        /* Currently, for trap, we do not advance IIP to next
54         * instruction. That's because we assume caller already
55         * set up IIP correctly
56         */
57
58        vcpu_set_iip(vcpu , regs->cr_iip);
59
60        /* set vifs.v to zero */
61        vifs = VCPU(vcpu,ifs);
62        vifs &= ~IA64_IFS_V;
63        vcpu_set_ifs(vcpu, vifs);
64
65        vcpu_set_iipa(vcpu, VMX(vcpu,cr_iipa));
66    }
67
68    vdcr = VCPU(vcpu,dcr);
69
70    /* Set guest psr
71     * up/mfl/mfh/pk/dt/rt/mc/it keeps unchanged
72     * be: set to the value of dcr.be
73     * pp: set to the value of dcr.pp
74     */
75    vpsr.val &= INITIAL_PSR_VALUE_AT_INTERRUPTION;
76    vpsr.val |= ( vdcr & IA64_DCR_BE);
77
78    /* VDCR pp bit position is different from VPSR pp bit */
79    if ( vdcr & IA64_DCR_PP ) {
80        vpsr.val |= IA64_PSR_PP;
81    } else {
82        vpsr.val &= ~IA64_PSR_PP;;
83    }
84
85    vmx_vcpu_set_psr(vcpu, vpsr.val);
86
87}
88
89void
90inject_guest_interruption(VCPU *vcpu, u64 vec)
91{
92    u64 viva;
93    REGS *regs;
94    ISR pt_isr;
95
96    perfc_incra(vmx_inject_guest_interruption, vec >> 8);
97
98    regs = vcpu_regs(vcpu);
99
100    // clear cr.isr.ir (incomplete register frame)
101    pt_isr.val = VMX(vcpu,cr_isr);
102    pt_isr.ir = 0;
103    VMX(vcpu,cr_isr) = pt_isr.val;
104
105    collect_interruption(vcpu);
106    vmx_ia64_set_dcr(vcpu);
107
108    vmx_vcpu_get_iva(vcpu,&viva);
109    regs->cr_iip = viva + vec;
110}
111
112
113/*
114 * Set vIFA & vITIR & vIHA, when vPSR.ic =1
115 * Parameter:
116 *  set_ifa: if true, set vIFA
117 *  set_itir: if true, set vITIR
118 *  set_iha: if true, set vIHA
119 */
120void
121set_ifa_itir_iha (VCPU *vcpu, u64 vadr,
122          int set_ifa, int set_itir, int set_iha)
123{
124    IA64_PSR vpsr;
125    u64 value;
126    vpsr.val = VCPU(vcpu, vpsr);
127    /* Vol2, Table 8-1 */
128    if ( vpsr.ic ) {
129        if ( set_ifa){
130            vcpu_set_ifa(vcpu, vadr);
131        }
132        if ( set_itir) {
133            value = vmx_vcpu_get_itir_on_fault(vcpu, vadr);
134            vcpu_set_itir(vcpu, value);
135        }
136
137        if ( set_iha) {
138            vmx_vcpu_thash(vcpu, vadr, &value);
139            vcpu_set_iha(vcpu, value);
140        }
141    }
142
143
144}
145
146/*
147 * Data TLB Fault
148 *  @ Data TLB vector
149 * Refer to SDM Vol2 Table 5-6 & 8-1
150 */
151void
152dtlb_fault (VCPU *vcpu, u64 vadr)
153{
154    /* If vPSR.ic, IFA, ITIR, IHA */
155    set_ifa_itir_iha (vcpu, vadr, 1, 1, 1);
156    inject_guest_interruption(vcpu,IA64_DATA_TLB_VECTOR);
157}
158
159/*
160 * Instruction TLB Fault
161 *  @ Instruction TLB vector
162 * Refer to SDM Vol2 Table 5-6 & 8-1
163 */
164void
165itlb_fault (VCPU *vcpu, u64 vadr)
166{
167     /* If vPSR.ic, IFA, ITIR, IHA */
168    set_ifa_itir_iha (vcpu, vadr, 1, 1, 1);
169    inject_guest_interruption(vcpu,IA64_INST_TLB_VECTOR);
170}
171
172
173
174/*
175 * Data Nested TLB Fault
176 *  @ Data Nested TLB Vector
177 * Refer to SDM Vol2 Table 5-6 & 8-1
178 */
179void
180nested_dtlb (VCPU *vcpu)
181{
182    inject_guest_interruption(vcpu,IA64_DATA_NESTED_TLB_VECTOR);
183}
184
185/*
186 * Alternate Data TLB Fault
187 *  @ Alternate Data TLB vector
188 * Refer to SDM Vol2 Table 5-6 & 8-1
189 */
190void
191alt_dtlb (VCPU *vcpu, u64 vadr)
192{
193    set_ifa_itir_iha (vcpu, vadr, 1, 1, 0);
194    inject_guest_interruption(vcpu,IA64_ALT_DATA_TLB_VECTOR);
195}
196
197
198/*
199 * Data TLB Fault
200 *  @ Data TLB vector
201 * Refer to SDM Vol2 Table 5-6 & 8-1
202 */
203void
204alt_itlb (VCPU *vcpu, u64 vadr)
205{
206    set_ifa_itir_iha (vcpu, vadr, 1, 1, 0);
207    inject_guest_interruption(vcpu,IA64_ALT_INST_TLB_VECTOR);
208}
209
210/* Deal with:
211 *  VHPT Translation Vector
212 */
213static void
214_vhpt_fault(VCPU *vcpu, u64 vadr)
215{
216    /* If vPSR.ic, IFA, ITIR, IHA*/
217    set_ifa_itir_iha (vcpu, vadr, 1, 1, 1);
218    inject_guest_interruption(vcpu,IA64_VHPT_TRANS_VECTOR);
219
220
221}
222
223/*
224 * VHPT Instruction Fault
225 *  @ VHPT Translation vector
226 * Refer to SDM Vol2 Table 5-6 & 8-1
227 */
228void
229ivhpt_fault (VCPU *vcpu, u64 vadr)
230{
231    _vhpt_fault(vcpu, vadr);
232}
233
234
235/*
236 * VHPT Data Fault
237 *  @ VHPT Translation vector
238 * Refer to SDM Vol2 Table 5-6 & 8-1
239 */
240void
241dvhpt_fault (VCPU *vcpu, u64 vadr)
242{
243    _vhpt_fault(vcpu, vadr);
244}
245
246
247
248/*
249 * Deal with:
250 *  General Exception vector
251 */
252void
253_general_exception (VCPU *vcpu)
254{
255    inject_guest_interruption(vcpu,IA64_GENEX_VECTOR);
256}
257
258
259/*
260 * Illegal Operation Fault
261 *  @ General Exception Vector
262 * Refer to SDM Vol2 Table 5-6 & 8-1
263 */
264void
265illegal_op (VCPU *vcpu)
266{
267    _general_exception(vcpu);
268}
269
270/*
271 * Illegal Dependency Fault
272 *  @ General Exception Vector
273 * Refer to SDM Vol2 Table 5-6 & 8-1
274 */
275void
276illegal_dep (VCPU *vcpu)
277{
278    _general_exception(vcpu);
279}
280
281/*
282 * Reserved Register/Field Fault
283 *  @ General Exception Vector
284 * Refer to SDM Vol2 Table 5-6 & 8-1
285 */
286void
287rsv_reg_field (VCPU *vcpu)
288{
289    _general_exception(vcpu);
290}
291/*
292 * Privileged Operation Fault
293 *  @ General Exception Vector
294 * Refer to SDM Vol2 Table 5-6 & 8-1
295 */
296
297void
298privilege_op (VCPU *vcpu)
299{
300    _general_exception(vcpu);
301}
302
303/*
304 * Unimplement Data Address Fault
305 *  @ General Exception Vector
306 * Refer to SDM Vol2 Table 5-6 & 8-1
307 */
308void
309unimpl_daddr (VCPU *vcpu)
310{
311    _general_exception(vcpu);
312}
313
314/*
315 * Privileged Register Fault
316 *  @ General Exception Vector
317 * Refer to SDM Vol2 Table 5-6 & 8-1
318 */
319void
320privilege_reg (VCPU *vcpu)
321{
322    _general_exception(vcpu);
323}
324
325/* Deal with
326 *  Nat consumption vector
327 * Parameter:
328 *  vaddr: Optional, if t == REGISTER
329 */
330static void
331_nat_consumption_fault(VCPU *vcpu, u64 vadr, miss_type t)
332{
333    /* If vPSR.ic && t == DATA/INST, IFA */
334    if ( t == DATA || t == INSTRUCTION ) {
335        /* IFA */
336        set_ifa_itir_iha (vcpu, vadr, 1, 0, 0);
337    }
338
339    inject_guest_interruption(vcpu,IA64_NAT_CONSUMPTION_VECTOR);
340}
341
342/*
343 * IR Data Nat Page Consumption Fault
344 *  @ Nat Consumption Vector
345 * Refer to SDM Vol2 Table 5-6 & 8-1
346 */
347#if 0
348static void
349ir_nat_page_consumption (VCPU *vcpu, u64 vadr)
350{
351    _nat_consumption_fault(vcpu, vadr, DATA);
352}
353#endif //shadow it due to no use currently
354
355/*
356 * Instruction Nat Page Consumption Fault
357 *  @ Nat Consumption Vector
358 * Refer to SDM Vol2 Table 5-6 & 8-1
359 */
360void
361inat_page_consumption (VCPU *vcpu, u64 vadr)
362{
363    _nat_consumption_fault(vcpu, vadr, INSTRUCTION);
364}
365
366/*
367 * Register Nat Consumption Fault
368 *  @ Nat Consumption Vector
369 * Refer to SDM Vol2 Table 5-6 & 8-1
370 */
371void
372rnat_consumption (VCPU *vcpu)
373{
374    _nat_consumption_fault(vcpu, 0, REGISTER);
375}
376
377/*
378 * Data Nat Page Consumption Fault
379 *  @ Nat Consumption Vector
380 * Refer to SDM Vol2 Table 5-6 & 8-1
381 */
382void
383dnat_page_consumption (VCPU *vcpu, uint64_t vadr)
384{
385    _nat_consumption_fault(vcpu, vadr, DATA);
386}
387
388/* Deal with
389 *  Page not present vector
390 */
391static void
392__page_not_present(VCPU *vcpu, u64 vadr)
393{
394    /* If vPSR.ic, IFA, ITIR */
395    set_ifa_itir_iha (vcpu, vadr, 1, 1, 0);
396    inject_guest_interruption(vcpu, IA64_PAGE_NOT_PRESENT_VECTOR);
397}
398
399
400void
401data_page_not_present(VCPU *vcpu, u64 vadr)
402{
403    __page_not_present(vcpu, vadr);
404}
405
406
407void
408inst_page_not_present(VCPU *vcpu, u64 vadr)
409{
410    __page_not_present(vcpu, vadr);
411}
412
413
414/* Deal with
415 *  Data access rights vector
416 */
417void
418data_access_rights(VCPU *vcpu, u64 vadr)
419{
420    /* If vPSR.ic, IFA, ITIR */
421    set_ifa_itir_iha (vcpu, vadr, 1, 1, 0);
422    inject_guest_interruption(vcpu, IA64_DATA_ACCESS_RIGHTS_VECTOR);
423}
424
Note: See TracBrowser for help on using the repository browser.