diff options
author | Jes Sorensen <jes@sgi.com> | 2009-02-25 11:38:52 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-06-10 04:48:28 -0400 |
commit | 0c72ea7fb8a39b4bba071b19f5f835af5b5e538a (patch) | |
tree | cd5749eb3952233180b7a263da9278e6d76f2669 /arch/ia64/kvm/kvm-ia64.c | |
parent | 58c2dde17d6eb6c8c0566e52d184aa16755d890f (diff) |
KVM: ia64: Map in SN2 RTC registers to the VMM module
On SN2, map in the SN2 RTC registers to the VMM module, needed for ITC
emulation.
Signed-off-by: Jes Sorensen <jes@sgi.com>
Acked-by: Xiantao Zhang <xiantao.zhang@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/ia64/kvm/kvm-ia64.c')
-rw-r--r-- | arch/ia64/kvm/kvm-ia64.c | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index acf43ec42704..14a3fabc7d62 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
@@ -41,6 +41,9 @@ | |||
41 | #include <asm/div64.h> | 41 | #include <asm/div64.h> |
42 | #include <asm/tlb.h> | 42 | #include <asm/tlb.h> |
43 | #include <asm/elf.h> | 43 | #include <asm/elf.h> |
44 | #include <asm/sn/addrs.h> | ||
45 | #include <asm/sn/clksupport.h> | ||
46 | #include <asm/sn/shub_mmr.h> | ||
44 | 47 | ||
45 | #include "misc.h" | 48 | #include "misc.h" |
46 | #include "vti.h" | 49 | #include "vti.h" |
@@ -119,8 +122,7 @@ void kvm_arch_hardware_enable(void *garbage) | |||
119 | unsigned long saved_psr; | 122 | unsigned long saved_psr; |
120 | int slot; | 123 | int slot; |
121 | 124 | ||
122 | pte = pte_val(mk_pte_phys(__pa(kvm_vmm_base), | 125 | pte = pte_val(mk_pte_phys(__pa(kvm_vmm_base), PAGE_KERNEL)); |
123 | PAGE_KERNEL)); | ||
124 | local_irq_save(saved_psr); | 126 | local_irq_save(saved_psr); |
125 | slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT); | 127 | slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT); |
126 | local_irq_restore(saved_psr); | 128 | local_irq_restore(saved_psr); |
@@ -425,6 +427,23 @@ static int handle_switch_rr6(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
425 | return 1; | 427 | return 1; |
426 | } | 428 | } |
427 | 429 | ||
430 | static int kvm_sn2_setup_mappings(struct kvm_vcpu *vcpu) | ||
431 | { | ||
432 | unsigned long pte, rtc_phys_addr, map_addr; | ||
433 | int slot; | ||
434 | |||
435 | map_addr = KVM_VMM_BASE + (1UL << KVM_VMM_SHIFT); | ||
436 | rtc_phys_addr = LOCAL_MMR_OFFSET | SH_RTC; | ||
437 | pte = pte_val(mk_pte_phys(rtc_phys_addr, PAGE_KERNEL_UC)); | ||
438 | slot = ia64_itr_entry(0x3, map_addr, pte, PAGE_SHIFT); | ||
439 | vcpu->arch.sn_rtc_tr_slot = slot; | ||
440 | if (slot < 0) { | ||
441 | printk(KERN_ERR "Mayday mayday! RTC mapping failed!\n"); | ||
442 | slot = 0; | ||
443 | } | ||
444 | return slot; | ||
445 | } | ||
446 | |||
428 | int kvm_emulate_halt(struct kvm_vcpu *vcpu) | 447 | int kvm_emulate_halt(struct kvm_vcpu *vcpu) |
429 | { | 448 | { |
430 | 449 | ||
@@ -563,18 +582,29 @@ static int kvm_insert_vmm_mapping(struct kvm_vcpu *vcpu) | |||
563 | if (r < 0) | 582 | if (r < 0) |
564 | goto out; | 583 | goto out; |
565 | vcpu->arch.vm_tr_slot = r; | 584 | vcpu->arch.vm_tr_slot = r; |
585 | |||
586 | #if defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC) | ||
587 | if (kvm->arch.is_sn2) { | ||
588 | r = kvm_sn2_setup_mappings(vcpu); | ||
589 | if (r < 0) | ||
590 | goto out; | ||
591 | } | ||
592 | #endif | ||
593 | |||
566 | r = 0; | 594 | r = 0; |
567 | out: | 595 | out: |
568 | return r; | 596 | return r; |
569 | |||
570 | } | 597 | } |
571 | 598 | ||
572 | static void kvm_purge_vmm_mapping(struct kvm_vcpu *vcpu) | 599 | static void kvm_purge_vmm_mapping(struct kvm_vcpu *vcpu) |
573 | { | 600 | { |
574 | 601 | struct kvm *kvm = vcpu->kvm; | |
575 | ia64_ptr_entry(0x3, vcpu->arch.vmm_tr_slot); | 602 | ia64_ptr_entry(0x3, vcpu->arch.vmm_tr_slot); |
576 | ia64_ptr_entry(0x3, vcpu->arch.vm_tr_slot); | 603 | ia64_ptr_entry(0x3, vcpu->arch.vm_tr_slot); |
577 | 604 | #if defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC) | |
605 | if (kvm->arch.is_sn2) | ||
606 | ia64_ptr_entry(0x3, vcpu->arch.sn_rtc_tr_slot); | ||
607 | #endif | ||
578 | } | 608 | } |
579 | 609 | ||
580 | static int kvm_vcpu_pre_transition(struct kvm_vcpu *vcpu) | 610 | static int kvm_vcpu_pre_transition(struct kvm_vcpu *vcpu) |
@@ -800,6 +830,9 @@ struct kvm *kvm_arch_create_vm(void) | |||
800 | 830 | ||
801 | if (IS_ERR(kvm)) | 831 | if (IS_ERR(kvm)) |
802 | return ERR_PTR(-ENOMEM); | 832 | return ERR_PTR(-ENOMEM); |
833 | |||
834 | kvm->arch.is_sn2 = ia64_platform_is("sn2"); | ||
835 | |||
803 | kvm_init_vm(kvm); | 836 | kvm_init_vm(kvm); |
804 | 837 | ||
805 | kvm->arch.online_vcpus = 0; | 838 | kvm->arch.online_vcpus = 0; |