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 | |
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>
-rw-r--r-- | arch/ia64/include/asm/kvm_host.h | 2 | ||||
-rw-r--r-- | arch/ia64/include/asm/pgtable.h | 2 | ||||
-rw-r--r-- | arch/ia64/kvm/kvm-ia64.c | 43 |
3 files changed, 42 insertions, 5 deletions
diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h index 5608488dc2da..12439956551b 100644 --- a/arch/ia64/include/asm/kvm_host.h +++ b/arch/ia64/include/asm/kvm_host.h | |||
@@ -371,6 +371,7 @@ struct kvm_vcpu_arch { | |||
371 | int last_run_cpu; | 371 | int last_run_cpu; |
372 | int vmm_tr_slot; | 372 | int vmm_tr_slot; |
373 | int vm_tr_slot; | 373 | int vm_tr_slot; |
374 | int sn_rtc_tr_slot; | ||
374 | 375 | ||
375 | #define KVM_MP_STATE_RUNNABLE 0 | 376 | #define KVM_MP_STATE_RUNNABLE 0 |
376 | #define KVM_MP_STATE_UNINITIALIZED 1 | 377 | #define KVM_MP_STATE_UNINITIALIZED 1 |
@@ -465,6 +466,7 @@ struct kvm_arch { | |||
465 | unsigned long vmm_init_rr; | 466 | unsigned long vmm_init_rr; |
466 | 467 | ||
467 | int online_vcpus; | 468 | int online_vcpus; |
469 | int is_sn2; | ||
468 | 470 | ||
469 | struct kvm_ioapic *vioapic; | 471 | struct kvm_ioapic *vioapic; |
470 | struct kvm_vm_stat stat; | 472 | struct kvm_vm_stat stat; |
diff --git a/arch/ia64/include/asm/pgtable.h b/arch/ia64/include/asm/pgtable.h index 7a9bff47564f..0a9cc73d35c7 100644 --- a/arch/ia64/include/asm/pgtable.h +++ b/arch/ia64/include/asm/pgtable.h | |||
@@ -146,6 +146,8 @@ | |||
146 | #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX) | 146 | #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX) |
147 | #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX) | 147 | #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX) |
148 | #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX) | 148 | #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX) |
149 | #define PAGE_KERNEL_UC __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX | \ | ||
150 | _PAGE_MA_UC) | ||
149 | 151 | ||
150 | # ifndef __ASSEMBLY__ | 152 | # ifndef __ASSEMBLY__ |
151 | 153 | ||
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; |