diff options
Diffstat (limited to 'arch/ia64/kvm/process.c')
-rw-r--r-- | arch/ia64/kvm/process.c | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/arch/ia64/kvm/process.c b/arch/ia64/kvm/process.c index f9c9504144fa..0e727ce0d55c 100644 --- a/arch/ia64/kvm/process.c +++ b/arch/ia64/kvm/process.c | |||
@@ -550,18 +550,60 @@ void reflect_interruption(u64 ifa, u64 isr, u64 iim, | |||
550 | inject_guest_interruption(vcpu, vector); | 550 | inject_guest_interruption(vcpu, vector); |
551 | } | 551 | } |
552 | 552 | ||
553 | static unsigned long kvm_trans_pal_call_args(struct kvm_vcpu *vcpu, | ||
554 | unsigned long arg) | ||
555 | { | ||
556 | struct thash_data *data; | ||
557 | unsigned long gpa, poff; | ||
558 | |||
559 | if (!is_physical_mode(vcpu)) { | ||
560 | /* Depends on caller to provide the DTR or DTC mapping.*/ | ||
561 | data = vtlb_lookup(vcpu, arg, D_TLB); | ||
562 | if (data) | ||
563 | gpa = data->page_flags & _PAGE_PPN_MASK; | ||
564 | else { | ||
565 | data = vhpt_lookup(arg); | ||
566 | if (!data) | ||
567 | return 0; | ||
568 | gpa = data->gpaddr & _PAGE_PPN_MASK; | ||
569 | } | ||
570 | |||
571 | poff = arg & (PSIZE(data->ps) - 1); | ||
572 | arg = PAGEALIGN(gpa, data->ps) | poff; | ||
573 | } | ||
574 | arg = kvm_gpa_to_mpa(arg << 1 >> 1); | ||
575 | |||
576 | return (unsigned long)__va(arg); | ||
577 | } | ||
578 | |||
553 | static void set_pal_call_data(struct kvm_vcpu *vcpu) | 579 | static void set_pal_call_data(struct kvm_vcpu *vcpu) |
554 | { | 580 | { |
555 | struct exit_ctl_data *p = &vcpu->arch.exit_data; | 581 | struct exit_ctl_data *p = &vcpu->arch.exit_data; |
582 | unsigned long gr28 = vcpu_get_gr(vcpu, 28); | ||
583 | unsigned long gr29 = vcpu_get_gr(vcpu, 29); | ||
584 | unsigned long gr30 = vcpu_get_gr(vcpu, 30); | ||
556 | 585 | ||
557 | /*FIXME:For static and stacked convention, firmware | 586 | /*FIXME:For static and stacked convention, firmware |
558 | * has put the parameters in gr28-gr31 before | 587 | * has put the parameters in gr28-gr31 before |
559 | * break to vmm !!*/ | 588 | * break to vmm !!*/ |
560 | 589 | ||
561 | p->u.pal_data.gr28 = vcpu_get_gr(vcpu, 28); | 590 | switch (gr28) { |
562 | p->u.pal_data.gr29 = vcpu_get_gr(vcpu, 29); | 591 | case PAL_PERF_MON_INFO: |
563 | p->u.pal_data.gr30 = vcpu_get_gr(vcpu, 30); | 592 | case PAL_HALT_INFO: |
593 | p->u.pal_data.gr29 = kvm_trans_pal_call_args(vcpu, gr29); | ||
594 | p->u.pal_data.gr30 = vcpu_get_gr(vcpu, 30); | ||
595 | break; | ||
596 | case PAL_BRAND_INFO: | ||
597 | p->u.pal_data.gr29 = gr29;; | ||
598 | p->u.pal_data.gr30 = kvm_trans_pal_call_args(vcpu, gr30); | ||
599 | break; | ||
600 | default: | ||
601 | p->u.pal_data.gr29 = gr29;; | ||
602 | p->u.pal_data.gr30 = vcpu_get_gr(vcpu, 30); | ||
603 | } | ||
604 | p->u.pal_data.gr28 = gr28; | ||
564 | p->u.pal_data.gr31 = vcpu_get_gr(vcpu, 31); | 605 | p->u.pal_data.gr31 = vcpu_get_gr(vcpu, 31); |
606 | |||
565 | p->exit_reason = EXIT_REASON_PAL_CALL; | 607 | p->exit_reason = EXIT_REASON_PAL_CALL; |
566 | } | 608 | } |
567 | 609 | ||