]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
KVM: ia64: Add the support for translating PAL Call's pointer args
authorXiantao Zhang <xiantao.zhang@intel.com>
Thu, 15 Jan 2009 10:08:36 +0000 (18:08 +0800)
committerAvi Kivity <avi@redhat.com>
Tue, 24 Mar 2009 09:03:06 +0000 (11:03 +0200)
Add the support to translate PAL Call's pointer args.

Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
arch/ia64/kvm/process.c

index f9c9504144facde9fd8e6f2fcc18cfb8e96488ca..0e727ce0d55c5ff7caaaa47bb7fb30636e3e96fd 100644 (file)
@@ -550,18 +550,60 @@ void reflect_interruption(u64 ifa, u64 isr, u64 iim,
        inject_guest_interruption(vcpu, vector);
 }
 
+static unsigned long kvm_trans_pal_call_args(struct kvm_vcpu *vcpu,
+                                               unsigned long arg)
+{
+       struct thash_data *data;
+       unsigned long gpa, poff;
+
+       if (!is_physical_mode(vcpu)) {
+               /* Depends on caller to provide the DTR or DTC mapping.*/
+               data = vtlb_lookup(vcpu, arg, D_TLB);
+               if (data)
+                       gpa = data->page_flags & _PAGE_PPN_MASK;
+               else {
+                       data = vhpt_lookup(arg);
+                       if (!data)
+                               return 0;
+                       gpa = data->gpaddr & _PAGE_PPN_MASK;
+               }
+
+               poff = arg & (PSIZE(data->ps) - 1);
+               arg = PAGEALIGN(gpa, data->ps) | poff;
+       }
+       arg = kvm_gpa_to_mpa(arg << 1 >> 1);
+
+       return (unsigned long)__va(arg);
+}
+
 static void set_pal_call_data(struct kvm_vcpu *vcpu)
 {
        struct exit_ctl_data *p = &vcpu->arch.exit_data;
+       unsigned long gr28 = vcpu_get_gr(vcpu, 28);
+       unsigned long gr29 = vcpu_get_gr(vcpu, 29);
+       unsigned long gr30 = vcpu_get_gr(vcpu, 30);
 
        /*FIXME:For static and stacked convention, firmware
         * has put the parameters in gr28-gr31 before
         * break to vmm  !!*/
 
-       p->u.pal_data.gr28 = vcpu_get_gr(vcpu, 28);
-       p->u.pal_data.gr29 = vcpu_get_gr(vcpu, 29);
-       p->u.pal_data.gr30 = vcpu_get_gr(vcpu, 30);
+       switch (gr28) {
+       case PAL_PERF_MON_INFO:
+       case PAL_HALT_INFO:
+               p->u.pal_data.gr29 =  kvm_trans_pal_call_args(vcpu, gr29);
+               p->u.pal_data.gr30 = vcpu_get_gr(vcpu, 30);
+               break;
+       case PAL_BRAND_INFO:
+               p->u.pal_data.gr29 = gr29;;
+               p->u.pal_data.gr30 = kvm_trans_pal_call_args(vcpu, gr30);
+               break;
+       default:
+               p->u.pal_data.gr29 = gr29;;
+               p->u.pal_data.gr30 = vcpu_get_gr(vcpu, 30);
+       }
+       p->u.pal_data.gr28 = gr28;
        p->u.pal_data.gr31 = vcpu_get_gr(vcpu, 31);
+
        p->exit_reason = EXIT_REASON_PAL_CALL;
 }