From 1ae0a13def678876b9acfb5ac1e2cf7d5d45a60d Mon Sep 17 00:00:00 2001 From: "Dong, Eddie" Date: Mon, 7 Jan 2008 13:20:25 +0200 Subject: KVM: MMU: Simplify hash table indexing Signed-off-by: Yaozu (Eddie) Dong Signed-off-by: Avi Kivity --- include/asm-x86/kvm_host.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 68ee390b2844..e076790ee794 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -58,7 +58,8 @@ #define KVM_PERMILLE_MMU_PAGES 20 #define KVM_MIN_ALLOC_MMU_PAGES 64 -#define KVM_NUM_MMU_PAGES 1024 +#define KVM_MMU_HASH_SHIFT 10 +#define KVM_NUM_MMU_PAGES (1 << KVM_MMU_HASH_SHIFT) #define KVM_MIN_FREE_MMU_PAGES 5 #define KVM_REFILL_PAGES 25 #define KVM_MAX_CPUID_ENTRIES 40 -- cgit v1.2.3 From 2384d2b32640839a4d4d260ca7c5aa4edbf68d91 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Thu, 17 Jan 2008 15:14:33 +0800 Subject: KVM: VMX: Enable Virtual Processor Identification (VPID) To allow TLB entries to be retained across VM entry and VM exit, the VMM can now identify distinct address spaces through a new virtual-processor ID (VPID) field of the VMCS. [avi: drop vpid_sync_all()] [avi: add "cc" to asm constraints] Signed-off-by: Sheng Yang Signed-off-by: Avi Kivity --- include/asm-x86/kvm_host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index e076790ee794..28e8177ea4a0 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -601,6 +601,7 @@ static inline void kvm_inject_gp(struct kvm_vcpu *vcpu, u32 error_code) #define ASM_VMX_VMWRITE_RSP_RDX ".byte 0x0f, 0x79, 0xd4" #define ASM_VMX_VMXOFF ".byte 0x0f, 0x01, 0xc4" #define ASM_VMX_VMXON_RAX ".byte 0xf3, 0x0f, 0xc7, 0x30" +#define ASM_VMX_INVVPID ".byte 0x66, 0x0f, 0x38, 0x81, 0x08" #define MSR_IA32_TIME_STAMP_COUNTER 0x010 -- cgit v1.2.3 From 31bb117eb48f2629e030ca547ca89a1c34150183 Mon Sep 17 00:00:00 2001 From: Hollis Blanchard Date: Mon, 28 Jan 2008 17:42:34 -0600 Subject: KVM: Use CONFIG_PREEMPT_NOTIFIERS around struct preempt_notifier This allows kvm_host.h to be #included even when struct preempt_notifier is undefined. This is needed to build ppc asm-offsets.h. Signed-off-by: Hollis Blanchard Signed-off-by: Avi Kivity --- include/linux/kvm_host.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 928b0d59e9ba..b90ca368dcf6 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -67,7 +67,9 @@ void kvm_io_bus_register_dev(struct kvm_io_bus *bus, struct kvm_vcpu { struct kvm *kvm; +#ifdef CONFIG_PREEMPT_NOTIFIERS struct preempt_notifier preempt_notifier; +#endif int vcpu_id; struct mutex mutex; int cpu; -- cgit v1.2.3 From f2b4b7ddf633ffa24ce7c89c9e0d8a06463484e3 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Thu, 31 Jan 2008 14:57:37 +0100 Subject: KVM: make EFER_RESERVED_BITS configurable for architecture code This patch give the SVM and VMX implementations the ability to add some bits the guest can set in its EFER register. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- include/asm-x86/kvm_host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 28e8177ea4a0..274f153c8704 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -430,6 +430,7 @@ void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw, unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr); void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long value, unsigned long *rflags); +void kvm_enable_efer_bits(u64); int kvm_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *data); int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data); -- cgit v1.2.3 From 1855267210e1a8c9d41fe3a3c7a0d42eca5fb7cd Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Thu, 7 Feb 2008 13:47:41 +0100 Subject: KVM: export information about NPT to generic x86 code The generic x86 code has to know if the specific implementation uses Nested Paging. In the generic code Nested Paging is called Two Dimensional Paging (TDP) to avoid confusion with (future) TDP implementations of other vendors. This patch exports the availability of TDP to the generic x86 code. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- include/asm-x86/kvm_host.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 274f153c8704..5c6ba2212b1b 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -493,6 +493,8 @@ int kvm_fix_hypercall(struct kvm_vcpu *vcpu); int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u32 error_code); +void kvm_enable_tdp(void); + int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3); int complete_pio(struct kvm_vcpu *vcpu); -- cgit v1.2.3 From cc4b6871e771e76dc1de06adb8aed261a1c66be8 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Thu, 7 Feb 2008 13:47:43 +0100 Subject: KVM: export the load_pdptrs() function to modules The load_pdptrs() function is required in the SVM module for NPT support. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- include/asm-x86/kvm_host.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 5c6ba2212b1b..623249890a0b 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -411,6 +411,8 @@ void kvm_mmu_zap_all(struct kvm *kvm); unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm); void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages); +int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3); + enum emulation_result { EMULATE_DONE, /* no further processing */ EMULATE_DO_MMIO, /* kvm_run filled with mmio request */ -- cgit v1.2.3 From 18068523d3a0b41fcee5b53cdb437a0ab4d65e4b Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Fri, 15 Feb 2008 17:52:47 -0200 Subject: KVM: paravirtualized clocksource: host part This is the host part of kvm clocksource implementation. As it does not include clockevents, it is a fairly simple implementation. We only have to register a per-vcpu area, and start writing to it periodically. The area is binary compatible with xen, as we use the same shadow_info structure. [marcelo: fix bad_page on MSR_KVM_SYSTEM_TIME] [avi: save full value of the msr, even if enable bit is clear] [avi: clear previous value of time_page] Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Marcelo Tosatti Signed-off-by: Avi Kivity --- include/asm-x86/kvm_host.h | 7 +++++++ include/asm-x86/kvm_para.h | 25 +++++++++++++++++++++++++ include/linux/kvm.h | 1 + 3 files changed, 33 insertions(+) (limited to 'include') diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 623249890a0b..90c80fd830fc 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -262,6 +262,11 @@ struct kvm_vcpu_arch { /* emulate context */ struct x86_emulate_ctxt emulate_ctxt; + + gpa_t time; + struct kvm_vcpu_time_info hv_clock; + unsigned int time_offset; + struct page *time_page; }; struct kvm_mem_alias { @@ -288,6 +293,8 @@ struct kvm_arch{ int round_robin_prev_vcpu; unsigned int tss_addr; struct page *apic_access_page; + + gpa_t wall_clock; }; struct kvm_vm_stat { diff --git a/include/asm-x86/kvm_para.h b/include/asm-x86/kvm_para.h index c6f3fd8d8c53..5ab7d3dbd357 100644 --- a/include/asm-x86/kvm_para.h +++ b/include/asm-x86/kvm_para.h @@ -10,10 +10,35 @@ * paravirtualization, the appropriate feature bit should be checked. */ #define KVM_CPUID_FEATURES 0x40000001 +#define KVM_FEATURE_CLOCKSOURCE 0 + +#define MSR_KVM_WALL_CLOCK 0x11 +#define MSR_KVM_SYSTEM_TIME 0x12 #ifdef __KERNEL__ #include +/* xen binary-compatible interface. See xen headers for details */ +struct kvm_vcpu_time_info { + uint32_t version; + uint32_t pad0; + uint64_t tsc_timestamp; + uint64_t system_time; + uint32_t tsc_to_system_mul; + int8_t tsc_shift; + int8_t pad[3]; +} __attribute__((__packed__)); /* 32 bytes */ + +struct kvm_wall_clock { + uint32_t wc_version; + uint32_t wc_sec; + uint32_t wc_nsec; +} __attribute__((__packed__)); + + +extern void kvmclock_init(void); + + /* This instruction is vmcall. On non-VT architectures, it will generate a * trap that we will then rewrite to the appropriate instruction. */ diff --git a/include/linux/kvm.h b/include/linux/kvm.h index c1ec04fd000d..94540b3c6872 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -233,6 +233,7 @@ struct kvm_vapic_addr { #define KVM_CAP_SET_TSS_ADDR 4 #define KVM_CAP_VAPIC 6 #define KVM_CAP_EXT_CPUID 7 +#define KVM_CAP_CLOCKSOURCE 8 /* * ioctls for VM fds -- cgit v1.2.3 From f725230af9ea03f6cc6f4a90e87aa428df46ec19 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Wed, 20 Feb 2008 11:53:16 +0200 Subject: KVM: Add API to retrieve the number of supported vcpus per vm Signed-off-by: Avi Kivity --- include/linux/kvm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 94540b3c6872..deb9c38f98e7 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -234,6 +234,7 @@ struct kvm_vapic_addr { #define KVM_CAP_VAPIC 6 #define KVM_CAP_EXT_CPUID 7 #define KVM_CAP_CLOCKSOURCE 8 +#define KVM_CAP_NR_VCPUS 9 /* returns max vcpus per vm */ /* * ioctls for VM fds -- cgit v1.2.3 From edbe6c325da48e707a3b31310c5ff5783cf6c0be Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Wed, 20 Feb 2008 11:56:51 +0200 Subject: KVM: Increase vcpu count to 16 With NPT support, scalability is much improved. Signed-off-by: Avi Kivity --- include/linux/kvm_host.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index b90ca368dcf6..f4deb9992625 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -24,7 +24,7 @@ #include -#define KVM_MAX_VCPUS 4 +#define KVM_MAX_VCPUS 16 #define KVM_MEMORY_SLOTS 8 /* memory slots that does not exposed to userspace */ #define KVM_PRIVATE_MEM_SLOTS 4 -- cgit v1.2.3 From a988b910ef816ed57e1cecbec14e98e906453f91 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Wed, 20 Feb 2008 11:59:20 +0200 Subject: KVM: Add API for determining the number of supported memory slots Signed-off-by: Avi Kivity --- include/linux/kvm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/kvm.h b/include/linux/kvm.h index deb9c38f98e7..e92e70324ea1 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -235,6 +235,7 @@ struct kvm_vapic_addr { #define KVM_CAP_EXT_CPUID 7 #define KVM_CAP_CLOCKSOURCE 8 #define KVM_CAP_NR_VCPUS 9 /* returns max vcpus per vm */ +#define KVM_CAP_NR_MEMSLOTS 10 /* returns max memory slots per vm */ /* * ioctls for VM fds -- cgit v1.2.3 From ef2979bd98dac86ea6a4cd9bdd6820a466108017 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Wed, 20 Feb 2008 12:04:47 +0200 Subject: KVM: Increase the number of user memory slots per vm Signed-off-by: Avi Kivity --- include/linux/kvm_host.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index f4deb9992625..eb88d32dd5c7 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -25,7 +25,7 @@ #include #define KVM_MAX_VCPUS 16 -#define KVM_MEMORY_SLOTS 8 +#define KVM_MEMORY_SLOTS 32 /* memory slots that does not exposed to userspace */ #define KVM_PRIVATE_MEM_SLOTS 4 -- cgit v1.2.3 From f11c3a8d84d7bf091bf963edd7104dd4ba6416c3 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Thu, 21 Feb 2008 01:00:30 +0530 Subject: KVM: Add stat counter for hypercalls Signed-off-by: Amit Shah Signed-off-by: Avi Kivity --- include/asm-x86/kvm_host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 90c80fd830fc..935ffa4db9f4 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -328,6 +328,7 @@ struct kvm_vcpu_stat { u32 fpu_reload; u32 insn_emulation; u32 insn_emulation_fail; + u32 hypercalls; }; struct descriptor_table { -- cgit v1.2.3 From 2e53d63acba75795aa226febd140f67c58c6a353 Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Wed, 20 Feb 2008 14:47:24 -0500 Subject: KVM: MMU: ignore zapped root pagetables Mark zapped root pagetables as invalid and ignore such pages during lookup. This is a problem with the cr3-target feature, where a zapped root table fools the faulting code into creating a read-only mapping. The result is a lockup if the instruction can't be emulated. Signed-off-by: Marcelo Tosatti Cc: Anthony Liguori Signed-off-by: Avi Kivity --- include/asm-x86/kvm_host.h | 1 + include/linux/kvm_host.h | 2 ++ 2 files changed, 3 insertions(+) (limited to 'include') diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 935ffa4db9f4..8c3f74b73524 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -141,6 +141,7 @@ union kvm_mmu_page_role { unsigned pad_for_nice_hex_output:6; unsigned metaphysical:1; unsigned access:3; + unsigned invalid:1; }; }; diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index eb88d32dd5c7..994278fb5883 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -37,6 +37,7 @@ #define KVM_REQ_TLB_FLUSH 0 #define KVM_REQ_MIGRATE_TIMER 1 #define KVM_REQ_REPORT_TPR_ACCESS 2 +#define KVM_REQ_MMU_RELOAD 3 struct kvm_vcpu; extern struct kmem_cache *kvm_vcpu_cache; @@ -190,6 +191,7 @@ void kvm_resched(struct kvm_vcpu *vcpu); void kvm_load_guest_fpu(struct kvm_vcpu *vcpu); void kvm_put_guest_fpu(struct kvm_vcpu *vcpu); void kvm_flush_remote_tlbs(struct kvm *kvm); +void kvm_reload_remote_mmus(struct kvm *kvm); long kvm_arch_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg); -- cgit v1.2.3 From 05da45583de9b383dc81dd695fe248431d6c9f2b Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Sat, 23 Feb 2008 11:44:30 -0300 Subject: KVM: MMU: large page support Create large pages mappings if the guest PTE's are marked as such and the underlying memory is hugetlbfs backed. If the largepage contains write-protected pages, a large pte is not used. Gives a consistent 2% improvement for data copies on ram mounted filesystem, without NPT/EPT. Anthony measures a 4% improvement on 4-way kernbench, with NPT. Signed-off-by: Marcelo Tosatti Signed-off-by: Avi Kivity --- include/asm-x86/kvm_host.h | 9 +++++++++ include/linux/kvm_host.h | 5 +++++ 2 files changed, 14 insertions(+) (limited to 'include') diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 8c3f74b73524..95473ef5a906 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -39,6 +39,13 @@ #define INVALID_PAGE (~(hpa_t)0) #define UNMAPPED_GVA (~(gpa_t)0) +/* shadow tables are PAE even on non-PAE hosts */ +#define KVM_HPAGE_SHIFT 21 +#define KVM_HPAGE_SIZE (1UL << KVM_HPAGE_SHIFT) +#define KVM_HPAGE_MASK (~(KVM_HPAGE_SIZE - 1)) + +#define KVM_PAGES_PER_HPAGE (KVM_HPAGE_SIZE / PAGE_SIZE) + #define DE_VECTOR 0 #define UD_VECTOR 6 #define NM_VECTOR 7 @@ -230,6 +237,7 @@ struct kvm_vcpu_arch { struct { gfn_t gfn; /* presumed gfn during guest pte update */ struct page *page; /* page corresponding to that gfn */ + int largepage; } update_pte; struct i387_fxsave_struct host_fx_image; @@ -307,6 +315,7 @@ struct kvm_vm_stat { u32 mmu_recycled; u32 mmu_cache_miss; u32 remote_tlb_flush; + u32 lpages; }; struct kvm_vcpu_stat { diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 994278fb5883..9750bb3c5a75 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -103,6 +103,10 @@ struct kvm_memory_slot { unsigned long flags; unsigned long *rmap; unsigned long *dirty_bitmap; + struct { + unsigned long rmap_pde; + int write_count; + } *lpage_info; unsigned long userspace_addr; int user_alloc; }; @@ -169,6 +173,7 @@ int kvm_arch_set_memory_region(struct kvm *kvm, int user_alloc); gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn); struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn); +unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn); void kvm_release_page_clean(struct page *page); void kvm_release_page_dirty(struct page *page); int kvm_read_guest_page(struct kvm *kvm, gfn_t gfn, void *data, int offset, -- cgit v1.2.3 From 2d3ad1f40c841bd3e97d30d423eea53915d085dc Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 24 Feb 2008 11:20:43 +0200 Subject: KVM: Prefix control register accessors with kvm_ to avoid namespace pollution Names like 'set_cr3()' look dangerously close to affecting the host. Signed-off-by: Avi Kivity --- include/asm-x86/kvm_host.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 95473ef5a906..49ced21e0290 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -470,12 +470,12 @@ int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value); -void set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0); -void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr0); -void set_cr4(struct kvm_vcpu *vcpu, unsigned long cr0); -void set_cr8(struct kvm_vcpu *vcpu, unsigned long cr0); -unsigned long get_cr8(struct kvm_vcpu *vcpu); -void lmsw(struct kvm_vcpu *vcpu, unsigned long msw); +void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0); +void kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr0); +void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr0); +void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr0); +unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu); +void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw); void kvm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l); int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata); -- cgit v1.2.3 From 71c4dfafc0932d92cc99c7e839d25174b0ce10a1 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Tue, 26 Feb 2008 16:49:16 +0100 Subject: KVM: detect if VCPU triple faults In the current inject_page_fault path KVM only checks if there is another PF pending and injects a DF then. But it has to check for a pending DF too to detect a shutdown condition in the VCPU. If this is not detected the VCPU goes to a PF -> DF -> PF loop when it should triple fault. This patch detects this condition and handles it with an KVM_SHUTDOWN exit to userspace. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- include/linux/kvm_host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 9750bb3c5a75..958e00371516 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -38,6 +38,7 @@ #define KVM_REQ_MIGRATE_TIMER 1 #define KVM_REQ_REPORT_TPR_ACCESS 2 #define KVM_REQ_MMU_RELOAD 3 +#define KVM_REQ_TRIPLE_FAULT 4 struct kvm_vcpu; extern struct kmem_cache *kvm_vcpu_cache; -- cgit v1.2.3 From 7837699fa6d7adf81f26ab73a5f6897ea1ab9d6a Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Mon, 28 Jan 2008 05:10:22 +0800 Subject: KVM: In kernel PIT model The patch moves the PIT model from userspace to kernel, and increases the timer accuracy greatly. [marcelo: make last_injected_time per-guest] Signed-off-by: Sheng Yang Signed-off-by: Marcelo Tosatti Tested-and-Acked-by: Alex Davis Signed-off-by: Avi Kivity --- include/asm-x86/kvm_host.h | 1 + include/linux/kvm.h | 2 ++ 2 files changed, 3 insertions(+) (limited to 'include') diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 49ced21e0290..26a313a09472 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -298,6 +298,7 @@ struct kvm_arch{ struct list_head active_mmu_pages; struct kvm_pic *vpic; struct kvm_ioapic *vioapic; + struct kvm_pit *vpit; int round_robin_prev_vcpu; unsigned int tss_addr; diff --git a/include/linux/kvm.h b/include/linux/kvm.h index e92e70324ea1..cefa9a2c7b89 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -236,6 +236,7 @@ struct kvm_vapic_addr { #define KVM_CAP_CLOCKSOURCE 8 #define KVM_CAP_NR_VCPUS 9 /* returns max vcpus per vm */ #define KVM_CAP_NR_MEMSLOTS 10 /* returns max memory slots per vm */ +#define KVM_CAP_PIT 11 /* * ioctls for VM fds @@ -258,6 +259,7 @@ struct kvm_vapic_addr { #define KVM_IRQ_LINE _IOW(KVMIO, 0x61, struct kvm_irq_level) #define KVM_GET_IRQCHIP _IOWR(KVMIO, 0x62, struct kvm_irqchip) #define KVM_SET_IRQCHIP _IOR(KVMIO, 0x63, struct kvm_irqchip) +#define KVM_CREATE_PIT _IO(KVMIO, 0x64) /* * ioctls for vcpu fds -- cgit v1.2.3 From e0f63cb9277b64850854aee301762beeeb463473 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Tue, 4 Mar 2008 00:50:59 +0800 Subject: KVM: Add save/restore supporting of in kernel PIT Signed-off-by: Sheng Yang Signed-off-by: Avi Kivity --- include/asm-x86/kvm.h | 21 +++++++++++++++++++++ include/linux/kvm.h | 2 ++ 2 files changed, 23 insertions(+) (limited to 'include') diff --git a/include/asm-x86/kvm.h b/include/asm-x86/kvm.h index 7a71120426a3..12b4b25371d5 100644 --- a/include/asm-x86/kvm.h +++ b/include/asm-x86/kvm.h @@ -188,4 +188,25 @@ struct kvm_cpuid2 { struct kvm_cpuid_entry2 entries[0]; }; +/* for KVM_GET_PIT and KVM_SET_PIT */ +struct kvm_pit_channel_state { + __u32 count; /* can be 65536 */ + __u16 latched_count; + __u8 count_latched; + __u8 status_latched; + __u8 status; + __u8 read_state; + __u8 write_state; + __u8 write_latch; + __u8 rw_mode; + __u8 mode; + __u8 bcd; + __u8 gate; + __s64 count_load_time; +}; + +struct kvm_pit_state { + struct kvm_pit_channel_state channels[3]; +}; + #endif diff --git a/include/linux/kvm.h b/include/linux/kvm.h index cefa9a2c7b89..a2f3274016ee 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -260,6 +260,8 @@ struct kvm_vapic_addr { #define KVM_GET_IRQCHIP _IOWR(KVMIO, 0x62, struct kvm_irqchip) #define KVM_SET_IRQCHIP _IOR(KVMIO, 0x63, struct kvm_irqchip) #define KVM_CREATE_PIT _IO(KVMIO, 0x64) +#define KVM_GET_PIT _IOWR(KVMIO, 0x65, struct kvm_pit_state) +#define KVM_SET_PIT _IOR(KVMIO, 0x66, struct kvm_pit_state) /* * ioctls for vcpu fds -- cgit v1.2.3 From a28e4f5a621289fe0d9c8a461b0c256f9e17f3bc Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Fri, 22 Feb 2008 12:21:36 -0500 Subject: KVM: add basic paravirt support Add basic KVM paravirt support. Avoid vm-exits on IO delays. Signed-off-by: Marcelo Tosatti Signed-off-by: Avi Kivity --- include/asm-x86/kvm_para.h | 3 ++- include/linux/kvm.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-x86/kvm_para.h b/include/asm-x86/kvm_para.h index 5ab7d3dbd357..ed5df3a54aab 100644 --- a/include/asm-x86/kvm_para.h +++ b/include/asm-x86/kvm_para.h @@ -10,7 +10,8 @@ * paravirtualization, the appropriate feature bit should be checked. */ #define KVM_CPUID_FEATURES 0x40000001 -#define KVM_FEATURE_CLOCKSOURCE 0 +#define KVM_FEATURE_CLOCKSOURCE 0 +#define KVM_FEATURE_NOP_IO_DELAY 1 #define MSR_KVM_WALL_CLOCK 0x11 #define MSR_KVM_SYSTEM_TIME 0x12 diff --git a/include/linux/kvm.h b/include/linux/kvm.h index a2f3274016ee..76f09474be98 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -237,6 +237,7 @@ struct kvm_vapic_addr { #define KVM_CAP_NR_VCPUS 9 /* returns max vcpus per vm */ #define KVM_CAP_NR_MEMSLOTS 10 /* returns max memory slots per vm */ #define KVM_CAP_PIT 11 +#define KVM_CAP_NOP_IO_DELAY 12 /* * ioctls for VM fds -- cgit v1.2.3 From 0cf1bfd2737f41e59f974a61eab11af206d2042a Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Fri, 22 Feb 2008 12:21:36 -0500 Subject: x86: KVM guest: add basic paravirt support Add basic KVM paravirt support. Avoid vm-exits on IO delays. Signed-off-by: Marcelo Tosatti Signed-off-by: Avi Kivity --- include/linux/kvm_para.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/linux/kvm_para.h b/include/linux/kvm_para.h index 5497aac0d2f8..9c462c91a6b1 100644 --- a/include/linux/kvm_para.h +++ b/include/linux/kvm_para.h @@ -20,6 +20,12 @@ #include #ifdef __KERNEL__ +#ifdef CONFIG_KVM_GUEST +void __init kvm_guest_init(void); +#else +#define kvm_guest_init() do { } while (0) +#endif + static inline int kvm_para_has_feature(unsigned int feature) { if (kvm_arch_para_features() & (1UL << feature)) -- cgit v1.2.3 From 9f81128591ca1e9907f2e7a7b195e33232167d60 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 2 Mar 2008 14:06:05 +0200 Subject: KVM: Provide unlocked version of emulator_write_phys() Signed-off-by: Avi Kivity --- include/asm-x86/kvm_host.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 26a313a09472..99d31f5ed9ff 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -432,6 +432,9 @@ void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages); int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3); +int __emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, + const void *val, int bytes); + enum emulation_result { EMULATE_DONE, /* no further processing */ EMULATE_DO_MMIO, /* kvm_run filled with mmio request */ -- cgit v1.2.3 From 2f333bcb4edd8daef99dabe4e7df8277af73cff1 Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Fri, 22 Feb 2008 12:21:37 -0500 Subject: KVM: MMU: hypercall based pte updates and TLB flushes Hypercall based pte updates are faster than faults, and also allow use of the lazy MMU mode to batch operations. Don't report the feature if two dimensional paging is enabled. [avi: - one mmu_op hypercall instead of one per op - allow 64-bit gpa on hypercall - don't pass host errors (-ENOMEM) to guest] [akpm: warning fix on i386] Signed-off-by: Marcelo Tosatti Signed-off-by: Andrew Morton Signed-off-by: Avi Kivity --- include/asm-x86/kvm_host.h | 4 ++++ include/asm-x86/kvm_para.h | 29 +++++++++++++++++++++++++++++ include/linux/kvm.h | 1 + include/linux/kvm_para.h | 5 ++++- 4 files changed, 38 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 99d31f5ed9ff..772ba95f0a0e 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -434,6 +434,10 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3); int __emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, const void *val, int bytes); +int kvm_pv_mmu_op(struct kvm_vcpu *vcpu, unsigned long bytes, + gpa_t addr, unsigned long *ret); + +extern bool tdp_enabled; enum emulation_result { EMULATE_DONE, /* no further processing */ diff --git a/include/asm-x86/kvm_para.h b/include/asm-x86/kvm_para.h index ed5df3a54aab..509845942070 100644 --- a/include/asm-x86/kvm_para.h +++ b/include/asm-x86/kvm_para.h @@ -12,10 +12,39 @@ #define KVM_CPUID_FEATURES 0x40000001 #define KVM_FEATURE_CLOCKSOURCE 0 #define KVM_FEATURE_NOP_IO_DELAY 1 +#define KVM_FEATURE_MMU_OP 2 #define MSR_KVM_WALL_CLOCK 0x11 #define MSR_KVM_SYSTEM_TIME 0x12 +#define KVM_MAX_MMU_OP_BATCH 32 + +/* Operations for KVM_HC_MMU_OP */ +#define KVM_MMU_OP_WRITE_PTE 1 +#define KVM_MMU_OP_FLUSH_TLB 2 +#define KVM_MMU_OP_RELEASE_PT 3 + +/* Payload for KVM_HC_MMU_OP */ +struct kvm_mmu_op_header { + __u32 op; + __u32 pad; +}; + +struct kvm_mmu_op_write_pte { + struct kvm_mmu_op_header header; + __u64 pte_phys; + __u64 pte_val; +}; + +struct kvm_mmu_op_flush_tlb { + struct kvm_mmu_op_header header; +}; + +struct kvm_mmu_op_release_pt { + struct kvm_mmu_op_header header; + __u64 pt_phys; +}; + #ifdef __KERNEL__ #include diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 76f09474be98..c1b502a50a01 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -238,6 +238,7 @@ struct kvm_vapic_addr { #define KVM_CAP_NR_MEMSLOTS 10 /* returns max memory slots per vm */ #define KVM_CAP_PIT 11 #define KVM_CAP_NOP_IO_DELAY 12 +#define KVM_CAP_PV_MMU 13 /* * ioctls for VM fds diff --git a/include/linux/kvm_para.h b/include/linux/kvm_para.h index 9c462c91a6b1..3ddce03766ca 100644 --- a/include/linux/kvm_para.h +++ b/include/linux/kvm_para.h @@ -11,8 +11,11 @@ /* Return values for hypercalls */ #define KVM_ENOSYS 1000 +#define KVM_EFAULT EFAULT +#define KVM_E2BIG E2BIG -#define KVM_HC_VAPIC_POLL_IRQ 1 +#define KVM_HC_VAPIC_POLL_IRQ 1 +#define KVM_HC_MMU_OP 2 /* * hypercalls use architecture specific -- cgit v1.2.3 From ed23dc6f5bc950ebbe683dd0bed1d5878230c171 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Mon, 17 Mar 2008 16:08:38 -0300 Subject: x86: allow machine_crash_shutdown to be replaced This patch a llows machine_crash_shutdown to be replaced, just like any of the other functions in machine_ops Signed-off-by: Glauber Costa Signed-off-by: Avi Kivity --- include/asm-x86/reboot.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-x86/reboot.h b/include/asm-x86/reboot.h index 6b5233b4f84b..0891a41cd7e9 100644 --- a/include/asm-x86/reboot.h +++ b/include/asm-x86/reboot.h @@ -15,5 +15,6 @@ struct machine_ops { extern struct machine_ops machine_ops; void machine_real_restart(unsigned char *code, int length); +void native_machine_crash_shutdown(struct pt_regs *regs); #endif /* _ASM_REBOOT_H */ -- cgit v1.2.3 From 3c62c62502bea24448d4e82aa1f33c7dbca61a32 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Mon, 17 Mar 2008 16:08:39 -0300 Subject: x86: make native_machine_shutdown non-static it will allow external users to call it. It is mainly useful for routines that will override its machine_ops field for its own special purposes, but want to call the normal shutdown routine after they're done Signed-off-by: Glauber Costa Signed-off-by: Avi Kivity --- include/asm-x86/reboot.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-x86/reboot.h b/include/asm-x86/reboot.h index 0891a41cd7e9..e63741f19392 100644 --- a/include/asm-x86/reboot.h +++ b/include/asm-x86/reboot.h @@ -16,5 +16,6 @@ extern struct machine_ops machine_ops; void machine_real_restart(unsigned char *code, int length); void native_machine_crash_shutdown(struct pt_regs *regs); +void native_machine_shutdown(void); #endif /* _ASM_REBOOT_H */ -- cgit v1.2.3 From 97646202bc3f190dfcb48a3d506ea2445717d392 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Wed, 12 Mar 2008 18:10:45 +0100 Subject: KVM: kvm.h: __user requires compiler.h include/linux/kvm.h defines struct kvm_dirty_log to [...] union { void __user *dirty_bitmap; /* one bit per page */ __u64 padding; }; __user requires compiler.h to compile. Currently, this works on x86 only coincidentally due to other include files. This patch makes kvm.h compile in all cases. Signed-off-by: Christian Borntraeger Signed-off-by: Avi Kivity --- include/linux/kvm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/kvm.h b/include/linux/kvm.h index c1b502a50a01..3bd38284bfe9 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -8,6 +8,7 @@ */ #include +#include #include #include -- cgit v1.2.3 From 69a9f69bb24d6d3dbf3d2ba542ddceeda40536d5 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Fri, 21 Mar 2008 12:38:23 +0200 Subject: KVM: Move some x86 specific constants and structures to include/asm-x86 Signed-off-by: Avi Kivity --- include/asm-x86/kvm_host.h | 13 +++++++++++++ include/linux/kvm_host.h | 13 ------------- 2 files changed, 13 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 772ba95f0a0e..2c85d01d0764 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -20,6 +20,13 @@ #include +#define KVM_MAX_VCPUS 16 +#define KVM_MEMORY_SLOTS 32 +/* memory slots that does not exposed to userspace */ +#define KVM_PRIVATE_MEM_SLOTS 4 + +#define KVM_PIO_PAGE_OFFSET 1 + #define CR3_PAE_RESERVED_BITS ((X86_CR3_PWT | X86_CR3_PCD) - 1) #define CR3_NONPAE_RESERVED_BITS ((PAGE_SIZE-1) & ~(X86_CR3_PWT | X86_CR3_PCD)) #define CR3_L_MODE_RESERVED_BITS (CR3_NONPAE_RESERVED_BITS | \ @@ -114,6 +121,12 @@ enum { #define KVM_NR_MEM_OBJS 40 +struct kvm_guest_debug { + int enabled; + unsigned long bp[4]; + int singlestep; +}; + /* * We don't want allocation failures within the mmu code, so we preallocate * enough memory for a single page fault in a cache. diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 958e00371516..f4e143621e35 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -24,13 +24,6 @@ #include -#define KVM_MAX_VCPUS 16 -#define KVM_MEMORY_SLOTS 32 -/* memory slots that does not exposed to userspace */ -#define KVM_PRIVATE_MEM_SLOTS 4 - -#define KVM_PIO_PAGE_OFFSET 1 - /* * vcpu->requests bit members */ @@ -43,12 +36,6 @@ struct kvm_vcpu; extern struct kmem_cache *kvm_vcpu_cache; -struct kvm_guest_debug { - int enabled; - unsigned long bp[4]; - int singlestep; -}; - /* * It would be nice to use something smarter than a linear search, TBD... * Thankfully we dont expect many devices to register (famous last words :), -- cgit v1.2.3 From 2e4d2653497856b102c90153f970c9e344ba96c6 Mon Sep 17 00:00:00 2001 From: Izik Eidus Date: Mon, 24 Mar 2008 19:38:34 +0200 Subject: KVM: x86: add functions to get the cpl of vcpu Signed-off-by: Izik Eidus Signed-off-by: Avi Kivity --- include/asm-x86/kvm_host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 2c85d01d0764..93e809c251ef 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -388,6 +388,7 @@ struct kvm_x86_ops { u64 (*get_segment_base)(struct kvm_vcpu *vcpu, int seg); void (*get_segment)(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); + int (*get_cpl)(struct kvm_vcpu *vcpu); void (*set_segment)(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu, int *db, int *l); -- cgit v1.2.3 From 37817f2982d0f559f90cecc66e150dd9d2c2df05 Mon Sep 17 00:00:00 2001 From: Izik Eidus Date: Mon, 24 Mar 2008 23:14:53 +0200 Subject: KVM: x86: hardware task switching support This emulates the x86 hardware task switch mechanism in software, as it is unsupported by either vmx or svm. It allows operating systems which use it, like freedos, to run as kvm guests. Signed-off-by: Izik Eidus Signed-off-by: Avi Kivity --- include/asm-x86/kvm_host.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include') diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 93e809c251ef..7b28cf949d55 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -492,6 +492,8 @@ int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value); +int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason); + void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0); void kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr0); void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr0); @@ -657,4 +659,11 @@ static inline void kvm_inject_gp(struct kvm_vcpu *vcpu, u32 error_code) #define RMODE_TSS_SIZE \ (TSS_BASE_SIZE + TSS_REDIRECTION_SIZE + TSS_IOPB_SIZE + 1) +enum { + TASK_SWITCH_CALL = 0, + TASK_SWITCH_IRET = 1, + TASK_SWITCH_JMP = 2, + TASK_SWITCH_GATE = 3, +}; + #endif -- cgit v1.2.3 From 402b08622d9ac6e32e25289573272e0f21bb58a7 Mon Sep 17 00:00:00 2001 From: Carsten Otte Date: Tue, 25 Mar 2008 18:47:10 +0100 Subject: s390: KVM preparation: provide hook to enable pgstes in user pagetable The SIE instruction on s390 uses the 2nd half of the page table page to virtualize the storage keys of a guest. This patch offers the s390_enable_sie function, which reorganizes the page tables of a single-threaded process to reserve space in the page table: s390_enable_sie makes sure that the process is single threaded and then uses dup_mm to create a new mm with reorganized page tables. The old mm is freed and the process has now a page status extended field after every page table. Code that wants to exploit pgstes should SELECT CONFIG_PGSTE. This patch has a small common code hit, namely making dup_mm non-static. Edit (Carsten): I've modified Martin's patch, following Jeremy Fitzhardinge's review feedback. Now we do have the prototype for dup_mm in include/linux/sched.h. Following Martin's suggestion, s390_enable_sie() does now call task_lock() to prevent race against ptrace modification of mm_users. Signed-off-by: Martin Schwidefsky Signed-off-by: Carsten Otte Acked-by: Andrew Morton Signed-off-by: Avi Kivity --- include/asm-s390/mmu.h | 1 + include/asm-s390/mmu_context.h | 8 +++++++- include/asm-s390/pgtable.h | 1 + include/linux/sched.h | 2 ++ 4 files changed, 11 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-s390/mmu.h b/include/asm-s390/mmu.h index 1698e29c5b20..5dd5e7b3476f 100644 --- a/include/asm-s390/mmu.h +++ b/include/asm-s390/mmu.h @@ -7,6 +7,7 @@ typedef struct { unsigned long asce_bits; unsigned long asce_limit; int noexec; + int pgstes; } mm_context_t; #endif diff --git a/include/asm-s390/mmu_context.h b/include/asm-s390/mmu_context.h index b5a34c6f91a9..4c2fbf48c9c4 100644 --- a/include/asm-s390/mmu_context.h +++ b/include/asm-s390/mmu_context.h @@ -20,7 +20,13 @@ static inline int init_new_context(struct task_struct *tsk, #ifdef CONFIG_64BIT mm->context.asce_bits |= _ASCE_TYPE_REGION3; #endif - mm->context.noexec = s390_noexec; + if (current->mm->context.pgstes) { + mm->context.noexec = 0; + mm->context.pgstes = 1; + } else { + mm->context.noexec = s390_noexec; + mm->context.pgstes = 0; + } mm->context.asce_limit = STACK_TOP_MAX; crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm)); return 0; diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h index 65154dc9a9e5..8e9a629dc199 100644 --- a/include/asm-s390/pgtable.h +++ b/include/asm-s390/pgtable.h @@ -966,6 +966,7 @@ static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) extern int add_shared_memory(unsigned long start, unsigned long size); extern int remove_shared_memory(unsigned long start, unsigned long size); +extern int s390_enable_sie(void); /* * No page table caches to initialise diff --git a/include/linux/sched.h b/include/linux/sched.h index d0bd97044abd..9a4f3e63e3bf 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1798,6 +1798,8 @@ extern void mmput(struct mm_struct *); extern struct mm_struct *get_task_mm(struct task_struct *task); /* Remove the current tasks stale references to the old mm_struct */ extern void mm_release(struct task_struct *, struct mm_struct *); +/* Allocate a new mm structure and copy contents from tsk->mm */ +extern struct mm_struct *dup_mm(struct task_struct *tsk); extern int copy_thread(int, unsigned long, unsigned long, unsigned long, struct task_struct *, struct pt_regs *); extern void flush_thread(void); -- cgit v1.2.3 From 5b7baf05783b1ac97a510243d7e82293416a7cf6 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Tue, 25 Mar 2008 18:47:12 +0100 Subject: s390: KVM preparation: host memory management changes for s390 kvm This patch changes the s390 memory management defintions to use the pgste field for dirty and reference bit tracking of host and guest code. Usually on s390, dirty and referenced are tracked in storage keys, which belong to the physical page. This changes with virtualization: The guest and host dirty/reference bits are defined to be the logical OR of the values for the mapping and the physical page. This patch implements the necessary changes in pgtable.h for s390. There is a common code change in mm/rmap.c, the call to page_test_and_clear_young must be moved. This is a no-op for all architecture but s390. page_referenced checks the referenced bits for the physiscal page and for all mappings: o The physical page is checked with page_test_and_clear_young. o The mappings are checked with ptep_test_and_clear_young and friends. Without pgstes (the current implementation on Linux s390) the physical page check is implemented but the mapping callbacks are no-ops because dirty and referenced are not tracked in the s390 page tables. The pgstes introduces guest and host dirty and reference bits for s390 in the host mapping. These mapping must be checked before page_test_and_clear_young resets the reference bit. Signed-off-by: Heiko Carstens Signed-off-by: Christian Borntraeger Acked-by: Martin Schwidefsky Acked-by: Andrew Morton Signed-off-by: Carsten Otte Signed-off-by: Avi Kivity --- include/asm-s390/pgtable.h | 92 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h index 8e9a629dc199..7fe5c4b6d82d 100644 --- a/include/asm-s390/pgtable.h +++ b/include/asm-s390/pgtable.h @@ -30,6 +30,7 @@ */ #ifndef __ASSEMBLY__ #include +#include #include #include @@ -258,6 +259,13 @@ extern char empty_zero_page[PAGE_SIZE]; * swap pte is 1011 and 0001, 0011, 0101, 0111 are invalid. */ +/* Page status table bits for virtualization */ +#define RCP_PCL_BIT 55 +#define RCP_HR_BIT 54 +#define RCP_HC_BIT 53 +#define RCP_GR_BIT 50 +#define RCP_GC_BIT 49 + #ifndef __s390x__ /* Bits in the segment table address-space-control-element */ @@ -513,6 +521,48 @@ static inline int pte_file(pte_t pte) #define __HAVE_ARCH_PTE_SAME #define pte_same(a,b) (pte_val(a) == pte_val(b)) +static inline void rcp_lock(pte_t *ptep) +{ +#ifdef CONFIG_PGSTE + unsigned long *pgste = (unsigned long *) (ptep + PTRS_PER_PTE); + preempt_disable(); + while (test_and_set_bit(RCP_PCL_BIT, pgste)) + ; +#endif +} + +static inline void rcp_unlock(pte_t *ptep) +{ +#ifdef CONFIG_PGSTE + unsigned long *pgste = (unsigned long *) (ptep + PTRS_PER_PTE); + clear_bit(RCP_PCL_BIT, pgste); + preempt_enable(); +#endif +} + +/* forward declaration for SetPageUptodate in page-flags.h*/ +static inline void page_clear_dirty(struct page *page); +#include + +static inline void ptep_rcp_copy(pte_t *ptep) +{ +#ifdef CONFIG_PGSTE + struct page *page = virt_to_page(pte_val(*ptep)); + unsigned int skey; + unsigned long *pgste = (unsigned long *) (ptep + PTRS_PER_PTE); + + skey = page_get_storage_key(page_to_phys(page)); + if (skey & _PAGE_CHANGED) + set_bit(RCP_GC_BIT, pgste); + if (skey & _PAGE_REFERENCED) + set_bit(RCP_GR_BIT, pgste); + if (test_and_clear_bit(RCP_HC_BIT, pgste)) + SetPageDirty(page); + if (test_and_clear_bit(RCP_HR_BIT, pgste)) + SetPageReferenced(page); +#endif +} + /* * query functions pte_write/pte_dirty/pte_young only work if * pte_present() is true. Undefined behaviour if not.. @@ -599,6 +649,8 @@ static inline void pmd_clear(pmd_t *pmd) static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { + if (mm->context.pgstes) + ptep_rcp_copy(ptep); pte_val(*ptep) = _PAGE_TYPE_EMPTY; if (mm->context.noexec) pte_val(ptep[PTRS_PER_PTE]) = _PAGE_TYPE_EMPTY; @@ -667,6 +719,24 @@ static inline pte_t pte_mkyoung(pte_t pte) static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) { +#ifdef CONFIG_PGSTE + unsigned long physpage; + int young; + unsigned long *pgste; + + if (!vma->vm_mm->context.pgstes) + return 0; + physpage = pte_val(*ptep) & PAGE_MASK; + pgste = (unsigned long *) (ptep + PTRS_PER_PTE); + + young = ((page_get_storage_key(physpage) & _PAGE_REFERENCED) != 0); + rcp_lock(ptep); + if (young) + set_bit(RCP_GR_BIT, pgste); + young |= test_and_clear_bit(RCP_HR_BIT, pgste); + rcp_unlock(ptep); + return young; +#endif return 0; } @@ -674,7 +744,13 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, static inline int ptep_clear_flush_young(struct vm_area_struct *vma, unsigned long address, pte_t *ptep) { - /* No need to flush TLB; bits are in storage key */ + /* No need to flush TLB + * On s390 reference bits are in storage key and never in TLB + * With virtualization we handle the reference bit, without we + * we can simply return */ +#ifdef CONFIG_PGSTE + return ptep_test_and_clear_young(vma, address, ptep); +#endif return 0; } @@ -693,15 +769,25 @@ static inline void __ptep_ipte(unsigned long address, pte_t *ptep) : "=m" (*ptep) : "m" (*ptep), "a" (pto), "a" (address)); } - pte_val(*ptep) = _PAGE_TYPE_EMPTY; } static inline void ptep_invalidate(struct mm_struct *mm, unsigned long address, pte_t *ptep) { + if (mm->context.pgstes) { + rcp_lock(ptep); + __ptep_ipte(address, ptep); + ptep_rcp_copy(ptep); + pte_val(*ptep) = _PAGE_TYPE_EMPTY; + rcp_unlock(ptep); + return; + } __ptep_ipte(address, ptep); - if (mm->context.noexec) + pte_val(*ptep) = _PAGE_TYPE_EMPTY; + if (mm->context.noexec) { __ptep_ipte(address, ptep + PTRS_PER_PTE); + pte_val(*(ptep + PTRS_PER_PTE)) = _PAGE_TYPE_EMPTY; + } } /* -- cgit v1.2.3 From 8a88ac6183975c73c65b45f365f6f3b875c1348b Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Tue, 25 Mar 2008 18:47:15 +0100 Subject: s390: KVM preparation: address of the 64bit extint parm in lowcore The address 0x11b8 is used by z/VM for pfault and diag 250 I/O to provide a 64 bit extint parameter. virtio uses the same address, so its time to update the lowcore structure. Acked-by: Martin Schwidefsky Signed-off-by: Christian Borntraeger Signed-off-by: Carsten Otte Signed-off-by: Avi Kivity --- include/asm-s390/lowcore.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/asm-s390/lowcore.h b/include/asm-s390/lowcore.h index 5de3efb31445..0bc51d52a899 100644 --- a/include/asm-s390/lowcore.h +++ b/include/asm-s390/lowcore.h @@ -381,27 +381,32 @@ struct _lowcore /* whether the kernel died with panic() or not */ __u32 panic_magic; /* 0xe00 */ - __u8 pad13[0x1200-0xe04]; /* 0xe04 */ + __u8 pad13[0x11b8-0xe04]; /* 0xe04 */ + + /* 64 bit extparam used for pfault, diag 250 etc */ + __u64 ext_params2; /* 0x11B8 */ + + __u8 pad14[0x1200-0x11C0]; /* 0x11C0 */ /* System info area */ __u64 floating_pt_save_area[16]; /* 0x1200 */ __u64 gpregs_save_area[16]; /* 0x1280 */ __u32 st_status_fixed_logout[4]; /* 0x1300 */ - __u8 pad14[0x1318-0x1310]; /* 0x1310 */ + __u8 pad15[0x1318-0x1310]; /* 0x1310 */ __u32 prefixreg_save_area; /* 0x1318 */ __u32 fpt_creg_save_area; /* 0x131c */ - __u8 pad15[0x1324-0x1320]; /* 0x1320 */ + __u8 pad16[0x1324-0x1320]; /* 0x1320 */ __u32 tod_progreg_save_area; /* 0x1324 */ __u32 cpu_timer_save_area[2]; /* 0x1328 */ __u32 clock_comp_save_area[2]; /* 0x1330 */ - __u8 pad16[0x1340-0x1338]; /* 0x1338 */ + __u8 pad17[0x1340-0x1338]; /* 0x1338 */ __u32 access_regs_save_area[16]; /* 0x1340 */ __u64 cregs_save_area[16]; /* 0x1380 */ /* align to the top of the prefix area */ - __u8 pad17[0x2000-0x1400]; /* 0x1400 */ + __u8 pad18[0x2000-0x1400]; /* 0x1400 */ #endif /* !__s390x__ */ } __attribute__((packed)); /* End structure*/ -- cgit v1.2.3 From b0c632db637d68ad39d9f97f452ce176253f5f4e Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 25 Mar 2008 18:47:20 +0100 Subject: KVM: s390: arch backend for the kvm kernel module This patch contains the port of Qumranet's kvm kernel module to IBM zSeries (aka s390x, mainframe) architecture. It uses the mainframe's virtualization instruction SIE to run virtual machines with up to 64 virtual CPUs each. This port is only usable on 64bit host kernels, and can only run 64bit guest kernels. However, running 31bit applications in guest userspace is possible. The following source files are introduced by this patch arch/s390/kvm/kvm-s390.c similar to arch/x86/kvm/x86.c, this implements all arch callbacks for kvm. __vcpu_run calls back into sie64a to enter the guest machine context arch/s390/kvm/sie64a.S assembler function sie64a, which enters guest context via SIE, and switches world before and after that include/asm-s390/kvm_host.h contains all vital data structures needed to run virtual machines on the mainframe include/asm-s390/kvm.h defines kvm_regs and friends for user access to guest register content arch/s390/kvm/gaccess.h functions similar to uaccess to access guest memory arch/s390/kvm/kvm-s390.h header file for kvm-s390 internals, extended by later patches Acked-by: Martin Schwidefsky Signed-off-by: Christian Borntraeger Signed-off-by: Heiko Carstens Signed-off-by: Carsten Otte Signed-off-by: Avi Kivity --- include/asm-s390/Kbuild | 1 + include/asm-s390/kvm.h | 41 +++++++++++++- include/asm-s390/kvm_host.h | 127 ++++++++++++++++++++++++++++++++++++++++++++ include/asm-s390/kvm_para.h | 30 +++++++++++ include/linux/kvm.h | 15 ++++++ 5 files changed, 213 insertions(+), 1 deletion(-) create mode 100644 include/asm-s390/kvm_host.h create mode 100644 include/asm-s390/kvm_para.h (limited to 'include') diff --git a/include/asm-s390/Kbuild b/include/asm-s390/Kbuild index e92b429d2be1..13c9805349f1 100644 --- a/include/asm-s390/Kbuild +++ b/include/asm-s390/Kbuild @@ -7,6 +7,7 @@ header-y += tape390.h header-y += ucontext.h header-y += vtoc.h header-y += zcrypt.h +header-y += kvm.h unifdef-y += cmb.h unifdef-y += debug.h diff --git a/include/asm-s390/kvm.h b/include/asm-s390/kvm.h index 573f2a351386..d74002f95794 100644 --- a/include/asm-s390/kvm.h +++ b/include/asm-s390/kvm.h @@ -1,6 +1,45 @@ #ifndef __LINUX_KVM_S390_H #define __LINUX_KVM_S390_H -/* s390 does not support KVM */ +/* + * asm-s390/kvm.h - KVM s390 specific structures and definitions + * + * Copyright IBM Corp. 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License (version 2 only) + * as published by the Free Software Foundation. + * + * Author(s): Carsten Otte + * Christian Borntraeger + */ +#include + +/* for KVM_GET_IRQCHIP and KVM_SET_IRQCHIP */ +struct kvm_pic_state { + /* no PIC for s390 */ +}; + +struct kvm_ioapic_state { + /* no IOAPIC for s390 */ +}; + +/* for KVM_GET_REGS and KVM_SET_REGS */ +struct kvm_regs { + /* general purpose regs for s390 */ + __u64 gprs[16]; +}; + +/* for KVM_GET_SREGS and KVM_SET_SREGS */ +struct kvm_sregs { + __u32 acrs[16]; + __u64 crs[16]; +}; + +/* for KVM_GET_FPU and KVM_SET_FPU */ +struct kvm_fpu { + __u32 fpc; + __u64 fprs[16]; +}; #endif diff --git a/include/asm-s390/kvm_host.h b/include/asm-s390/kvm_host.h new file mode 100644 index 000000000000..c9d653333106 --- /dev/null +++ b/include/asm-s390/kvm_host.h @@ -0,0 +1,127 @@ +/* + * asm-s390/kvm_host.h - definition for kernel virtual machines on s390 + * + * Copyright IBM Corp. 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License (version 2 only) + * as published by the Free Software Foundation. + * + * Author(s): Carsten Otte + */ + + +#ifndef ASM_KVM_HOST_H +#define ASM_KVM_HOST_H +#include +#include + +#define KVM_MAX_VCPUS 64 +#define KVM_MEMORY_SLOTS 32 +/* memory slots that does not exposed to userspace */ +#define KVM_PRIVATE_MEM_SLOTS 4 + +struct kvm_guest_debug { +}; + +struct sca_entry { + atomic_t scn; + __u64 reserved; + __u64 sda; + __u64 reserved2[2]; +} __attribute__((packed)); + + +struct sca_block { + __u64 ipte_control; + __u64 reserved[5]; + __u64 mcn; + __u64 reserved2; + struct sca_entry cpu[64]; +} __attribute__((packed)); + +#define KVM_PAGES_PER_HPAGE 256 + +#define CPUSTAT_HOST 0x80000000 +#define CPUSTAT_WAIT 0x10000000 +#define CPUSTAT_ECALL_PEND 0x08000000 +#define CPUSTAT_STOP_INT 0x04000000 +#define CPUSTAT_IO_INT 0x02000000 +#define CPUSTAT_EXT_INT 0x01000000 +#define CPUSTAT_RUNNING 0x00800000 +#define CPUSTAT_RETAINED 0x00400000 +#define CPUSTAT_TIMING_SUB 0x00020000 +#define CPUSTAT_SIE_SUB 0x00010000 +#define CPUSTAT_RRF 0x00008000 +#define CPUSTAT_SLSV 0x00004000 +#define CPUSTAT_SLSR 0x00002000 +#define CPUSTAT_ZARCH 0x00000800 +#define CPUSTAT_MCDS 0x00000100 +#define CPUSTAT_SM 0x00000080 +#define CPUSTAT_G 0x00000008 +#define CPUSTAT_J 0x00000002 +#define CPUSTAT_P 0x00000001 + +struct sie_block { + atomic_t cpuflags; /* 0x0000 */ + __u32 prefix; /* 0x0004 */ + __u8 reserved8[32]; /* 0x0008 */ + __u64 cputm; /* 0x0028 */ + __u64 ckc; /* 0x0030 */ + __u64 epoch; /* 0x0038 */ + __u8 reserved40[4]; /* 0x0040 */ + __u16 lctl; /* 0x0044 */ + __s16 icpua; /* 0x0046 */ + __u32 ictl; /* 0x0048 */ + __u32 eca; /* 0x004c */ + __u8 icptcode; /* 0x0050 */ + __u8 reserved51; /* 0x0051 */ + __u16 ihcpu; /* 0x0052 */ + __u8 reserved54[2]; /* 0x0054 */ + __u16 ipa; /* 0x0056 */ + __u32 ipb; /* 0x0058 */ + __u32 scaoh; /* 0x005c */ + __u8 reserved60; /* 0x0060 */ + __u8 ecb; /* 0x0061 */ + __u8 reserved62[2]; /* 0x0062 */ + __u32 scaol; /* 0x0064 */ + __u8 reserved68[4]; /* 0x0068 */ + __u32 todpr; /* 0x006c */ + __u8 reserved70[16]; /* 0x0070 */ + __u64 gmsor; /* 0x0080 */ + __u64 gmslm; /* 0x0088 */ + psw_t gpsw; /* 0x0090 */ + __u64 gg14; /* 0x00a0 */ + __u64 gg15; /* 0x00a8 */ + __u8 reservedb0[80]; /* 0x00b0 */ + __u64 gcr[16]; /* 0x0100 */ + __u64 gbea; /* 0x0180 */ + __u8 reserved188[120]; /* 0x0188 */ +} __attribute__((packed)); + +struct kvm_vcpu_stat { + u32 exit_userspace; +}; + +struct kvm_vcpu_arch { + struct sie_block *sie_block; + unsigned long guest_gprs[16]; + s390_fp_regs host_fpregs; + unsigned int host_acrs[NUM_ACRS]; + s390_fp_regs guest_fpregs; + unsigned int guest_acrs[NUM_ACRS]; +}; + +struct kvm_vm_stat { + u32 remote_tlb_flush; +}; + +struct kvm_arch{ + unsigned long guest_origin; + unsigned long guest_memsize; + struct sca_block *sca; + debug_info_t *dbf; +}; + +extern int sie64a(struct sie_block *, __u64 *); +#endif diff --git a/include/asm-s390/kvm_para.h b/include/asm-s390/kvm_para.h new file mode 100644 index 000000000000..e9bd3fbe878c --- /dev/null +++ b/include/asm-s390/kvm_para.h @@ -0,0 +1,30 @@ +/* + * asm-s390/kvm_para.h - definition for paravirtual devices on s390 + * + * Copyright IBM Corp. 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License (version 2 only) + * as published by the Free Software Foundation. + * + * Author(s): Christian Borntraeger + */ + +#ifndef __S390_KVM_PARA_H +#define __S390_KVM_PARA_H + +/* + * No hypercalls for KVM on s390 + */ + +static inline int kvm_para_available(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_para_features(void) +{ + return 0; +} + +#endif /* __S390_KVM_PARA_H */ diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 3bd38284bfe9..2367ff0c5dd0 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -205,6 +205,11 @@ struct kvm_vapic_addr { __u64 vapic_addr; }; +struct kvm_s390_psw { + __u64 mask; + __u64 addr; +}; + #define KVMIO 0xAE /* @@ -213,6 +218,8 @@ struct kvm_vapic_addr { #define KVM_GET_API_VERSION _IO(KVMIO, 0x00) #define KVM_CREATE_VM _IO(KVMIO, 0x01) /* returns a VM fd */ #define KVM_GET_MSR_INDEX_LIST _IOWR(KVMIO, 0x02, struct kvm_msr_list) + +#define KVM_S390_ENABLE_SIE _IO(KVMIO, 0x06) /* * Check if a kvm extension is available. Argument is extension number, * return is 1 (yes) or 0 (no, sorry). @@ -291,5 +298,13 @@ struct kvm_vapic_addr { #define KVM_TPR_ACCESS_REPORTING _IOWR(KVMIO, 0x92, struct kvm_tpr_access_ctl) /* Available with KVM_CAP_VAPIC */ #define KVM_SET_VAPIC_ADDR _IOW(KVMIO, 0x93, struct kvm_vapic_addr) +/* store status for s390 */ +#define KVM_S390_STORE_STATUS_NOADDR (-1ul) +#define KVM_S390_STORE_STATUS_PREFIXED (-2ul) +#define KVM_S390_STORE_STATUS _IOW(KVMIO, 0x95, unsigned long) +/* initial ipl psw for s390 */ +#define KVM_S390_SET_INITIAL_PSW _IOW(KVMIO, 0x96, struct kvm_s390_psw) +/* initial reset for s390 */ +#define KVM_S390_INITIAL_RESET _IO(KVMIO, 0x97) #endif -- cgit v1.2.3 From 8f2abe6a1e525e878bdf58f68ccd146d543fde84 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Tue, 25 Mar 2008 18:47:23 +0100 Subject: KVM: s390: sie intercept handling This path introduces handling of sie intercepts in three flavors: Intercepts are either handled completely in-kernel by kvm_handle_sie_intercept(), or passed to userspace with corresponding data in struct kvm_run in case kvm_handle_sie_intercept() returns -ENOTSUPP. In case of partial execution in kernel with the need of userspace support, kvm_handle_sie_intercept() may choose to set up struct kvm_run and return -EREMOTE. The trivial intercept reasons are handled in this patch: handle_noop() just does nothing for intercepts that don't require our support at all handle_stop() is called when a cpu enters stopped state, and it drops out to userland after updating our vcpu state handle_validity() faults in the cpu lowcore if needed, or passes the request to userland Acked-by: Martin Schwidefsky Signed-off-by: Christian Borntraeger Signed-off-by: Carsten Otte Signed-off-by: Avi Kivity --- include/asm-s390/kvm_host.h | 4 ++++ include/linux/kvm.h | 9 +++++++++ 2 files changed, 13 insertions(+) (limited to 'include') diff --git a/include/asm-s390/kvm_host.h b/include/asm-s390/kvm_host.h index c9d653333106..8965b38d0a32 100644 --- a/include/asm-s390/kvm_host.h +++ b/include/asm-s390/kvm_host.h @@ -101,6 +101,10 @@ struct sie_block { struct kvm_vcpu_stat { u32 exit_userspace; + u32 exit_external_request; + u32 exit_external_interrupt; + u32 exit_stop_request; + u32 exit_validity; }; struct kvm_vcpu_arch { diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 2367ff0c5dd0..f2acd6b9ab4d 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -74,6 +74,7 @@ struct kvm_irqchip { #define KVM_EXIT_INTR 10 #define KVM_EXIT_SET_TPR 11 #define KVM_EXIT_TPR_ACCESS 12 +#define KVM_EXIT_S390_SIEIC 13 /* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */ struct kvm_run { @@ -138,6 +139,14 @@ struct kvm_run { __u32 is_write; __u32 pad; } tpr_access; + /* KVM_EXIT_S390_SIEIC */ + struct { + __u8 icptcode; + __u64 mask; /* psw upper half */ + __u64 addr; /* psw lower half */ + __u16 ipa; + __u32 ipb; + } s390_sieic; /* Fix the size of the union. */ char padding[256]; }; -- cgit v1.2.3 From ba5c1e9b6ceebdc39343cc03eb39f077abd3c571 Mon Sep 17 00:00:00 2001 From: Carsten Otte Date: Tue, 25 Mar 2008 18:47:26 +0100 Subject: KVM: s390: interrupt subsystem, cpu timer, waitpsw This patch contains the s390 interrupt subsystem (similar to in kernel apic) including timer interrupts (similar to in-kernel-pit) and enabled wait (similar to in kernel hlt). In order to achieve that, this patch also introduces intercept handling for instruction intercepts, and it implements load control instructions. This patch introduces an ioctl KVM_S390_INTERRUPT which is valid for both the vm file descriptors and the vcpu file descriptors. In case this ioctl is issued against a vm file descriptor, the interrupt is considered floating. Floating interrupts may be delivered to any virtual cpu in the configuration. The following interrupts are supported: SIGP STOP - interprocessor signal that stops a remote cpu SIGP SET PREFIX - interprocessor signal that sets the prefix register of a (stopped) remote cpu INT EMERGENCY - interprocessor interrupt, usually used to signal need_reshed and for smp_call_function() in the guest. PROGRAM INT - exception during program execution such as page fault, illegal instruction and friends RESTART - interprocessor signal that starts a stopped cpu INT VIRTIO - floating interrupt for virtio signalisation INT SERVICE - floating interrupt for signalisations from the system service processor struct kvm_s390_interrupt, which is submitted as ioctl parameter when injecting an interrupt, also carrys parameter data for interrupts along with the interrupt type. Interrupts on s390 usually have a state that represents the current operation, or identifies which device has caused the interruption on s390. kvm_s390_handle_wait() does handle waitpsw in two flavors: in case of a disabled wait (that is, disabled for interrupts), we exit to userspace. In case of an enabled wait we set up a timer that equals the cpu clock comparator value and sleep on a wait queue. [christian: change virtio interrupt to 0x2603] Acked-by: Martin Schwidefsky Signed-off-by: Heiko Carstens Signed-off-by: Carsten Otte Signed-off-by: Christian Borntraeger Signed-off-by: Avi Kivity --- include/asm-s390/kvm_host.h | 75 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/kvm.h | 17 ++++++++++ 2 files changed, 92 insertions(+) (limited to 'include') diff --git a/include/asm-s390/kvm_host.h b/include/asm-s390/kvm_host.h index 8965b38d0a32..4fe19305888a 100644 --- a/include/asm-s390/kvm_host.h +++ b/include/asm-s390/kvm_host.h @@ -70,6 +70,7 @@ struct sie_block { __u64 ckc; /* 0x0030 */ __u64 epoch; /* 0x0038 */ __u8 reserved40[4]; /* 0x0040 */ +#define LCTL_CR0 0x8000 __u16 lctl; /* 0x0044 */ __s16 icpua; /* 0x0046 */ __u32 ictl; /* 0x0048 */ @@ -105,8 +106,79 @@ struct kvm_vcpu_stat { u32 exit_external_interrupt; u32 exit_stop_request; u32 exit_validity; + u32 exit_instruction; + u32 instruction_lctl; + u32 instruction_lctg; + u32 exit_program_interruption; + u32 exit_instr_and_program; + u32 deliver_emergency_signal; + u32 deliver_service_signal; + u32 deliver_virtio_interrupt; + u32 deliver_stop_signal; + u32 deliver_prefix_signal; + u32 deliver_restart_signal; + u32 deliver_program_int; + u32 exit_wait_state; }; +struct io_info { + __u16 subchannel_id; /* 0x0b8 */ + __u16 subchannel_nr; /* 0x0ba */ + __u32 io_int_parm; /* 0x0bc */ + __u32 io_int_word; /* 0x0c0 */ +}; + +struct ext_info { + __u32 ext_params; + __u64 ext_params2; +}; + +#define PGM_OPERATION 0x01 +#define PGM_PRIVILEGED_OPERATION 0x02 +#define PGM_EXECUTE 0x03 +#define PGM_PROTECTION 0x04 +#define PGM_ADDRESSING 0x05 +#define PGM_SPECIFICATION 0x06 +#define PGM_DATA 0x07 + +struct pgm_info { + __u16 code; +}; + +struct prefix_info { + __u32 address; +}; + +struct interrupt_info { + struct list_head list; + u64 type; + union { + struct io_info io; + struct ext_info ext; + struct pgm_info pgm; + struct prefix_info prefix; + }; +}; + +struct local_interrupt { + spinlock_t lock; + struct list_head list; + atomic_t active; + struct float_interrupt *float_int; + int timer_due; /* event indicator for waitqueue below */ + wait_queue_head_t wq; +}; + +struct float_interrupt { + spinlock_t lock; + struct list_head list; + atomic_t active; + int next_rr_cpu; + unsigned long idle_mask [(64 + sizeof(long) - 1) / sizeof(long)]; + struct local_interrupt *local_int[64]; +}; + + struct kvm_vcpu_arch { struct sie_block *sie_block; unsigned long guest_gprs[16]; @@ -114,6 +186,8 @@ struct kvm_vcpu_arch { unsigned int host_acrs[NUM_ACRS]; s390_fp_regs guest_fpregs; unsigned int guest_acrs[NUM_ACRS]; + struct local_interrupt local_int; + struct timer_list ckc_timer; }; struct kvm_vm_stat { @@ -125,6 +199,7 @@ struct kvm_arch{ unsigned long guest_memsize; struct sca_block *sca; debug_info_t *dbf; + struct float_interrupt float_int; }; extern int sie64a(struct sie_block *, __u64 *); diff --git a/include/linux/kvm.h b/include/linux/kvm.h index f2acd6b9ab4d..029f0284a2fd 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -219,6 +219,21 @@ struct kvm_s390_psw { __u64 addr; }; +/* valid values for type in kvm_s390_interrupt */ +#define KVM_S390_SIGP_STOP 0xfffe0000u +#define KVM_S390_PROGRAM_INT 0xfffe0001u +#define KVM_S390_SIGP_SET_PREFIX 0xfffe0002u +#define KVM_S390_RESTART 0xfffe0003u +#define KVM_S390_INT_VIRTIO 0xffff2603u +#define KVM_S390_INT_SERVICE 0xffff2401u +#define KVM_S390_INT_EMERGENCY 0xffff1201u + +struct kvm_s390_interrupt { + __u32 type; + __u32 parm; + __u64 parm64; +}; + #define KVMIO 0xAE /* @@ -307,6 +322,8 @@ struct kvm_s390_psw { #define KVM_TPR_ACCESS_REPORTING _IOWR(KVMIO, 0x92, struct kvm_tpr_access_ctl) /* Available with KVM_CAP_VAPIC */ #define KVM_SET_VAPIC_ADDR _IOW(KVMIO, 0x93, struct kvm_vapic_addr) +/* valid for virtual machine (for floating interrupt)_and_ vcpu */ +#define KVM_S390_INTERRUPT _IOW(KVMIO, 0x94, struct kvm_s390_interrupt) /* store status for s390 */ #define KVM_S390_STORE_STATUS_NOADDR (-1ul) #define KVM_S390_STORE_STATUS_PREFIXED (-2ul) -- cgit v1.2.3 From 453423dce2785b8e22077e3b3eeecb4f60fe3470 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Tue, 25 Mar 2008 18:47:29 +0100 Subject: KVM: s390: intercepts for privileged instructions This patch introduces in-kernel handling of some intercepts for privileged instructions: handle_set_prefix() sets the prefix register of the local cpu handle_store_prefix() stores the content of the prefix register to memory handle_store_cpu_address() stores the cpu number of the current cpu to memory handle_skey() just decrements the instruction address and retries handle_stsch() delivers condition code 3 "operation not supported" handle_chsc() same here handle_stfl() stores the facility list which contains the capabilities of the cpu handle_stidp() stores cpu type/model/revision and such handle_stsi() stores information about the system topology Acked-by: Martin Schwidefsky Signed-off-by: Christian Borntraeger Signed-off-by: Heiko Carstens Signed-off-by: Carsten Otte Signed-off-by: Avi Kivity --- include/asm-s390/kvm_host.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include') diff --git a/include/asm-s390/kvm_host.h b/include/asm-s390/kvm_host.h index 4fe19305888a..2eaf6fede025 100644 --- a/include/asm-s390/kvm_host.h +++ b/include/asm-s390/kvm_host.h @@ -119,6 +119,15 @@ struct kvm_vcpu_stat { u32 deliver_restart_signal; u32 deliver_program_int; u32 exit_wait_state; + u32 instruction_stidp; + u32 instruction_spx; + u32 instruction_stpx; + u32 instruction_stap; + u32 instruction_storage_key; + u32 instruction_stsch; + u32 instruction_chsc; + u32 instruction_stsi; + u32 instruction_stfl; }; struct io_info { @@ -188,6 +197,10 @@ struct kvm_vcpu_arch { unsigned int guest_acrs[NUM_ACRS]; struct local_interrupt local_int; struct timer_list ckc_timer; + union { + cpuid_t cpu_id; + u64 stidp_data; + }; }; struct kvm_vm_stat { -- cgit v1.2.3 From 5288fbf0ef041ba0e8b4dcb2df4536b5e3a48b32 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Tue, 25 Mar 2008 18:47:31 +0100 Subject: KVM: s390: interprocessor communication via sigp This patch introduces in-kernel handling of _some_ sigp interprocessor signals (similar to ipi). kvm_s390_handle_sigp() decodes the sigp instruction and calls individual handlers depending on the operation requested: - sigp sense tries to retrieve information such as existence or running state of the remote cpu - sigp emergency sends an external interrupt to the remove cpu - sigp stop stops a remove cpu - sigp stop store status stops a remote cpu, and stores its entire internal state to the cpus lowcore - sigp set arch sets the architecture mode of the remote cpu. setting to ESAME (s390x 64bit) is accepted, setting to ESA/S390 (s390, 31 or 24 bit) is denied, all others are passed to userland - sigp set prefix sets the prefix register of a remote cpu For implementation of this, the stop intercept indication starts to get reused on purpose: a set of action bits defines what to do once a cpu gets stopped: ACTION_STOP_ON_STOP really stops the cpu when a stop intercept is recognized ACTION_STORE_ON_STOP stores the cpu status to lowcore when a stop intercept is recognized Acked-by: Martin Schwidefsky Signed-off-by: Christian Borntraeger Signed-off-by: Carsten Otte Signed-off-by: Carsten Otte Signed-off-by: Avi Kivity --- include/asm-s390/kvm_host.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include') diff --git a/include/asm-s390/kvm_host.h b/include/asm-s390/kvm_host.h index 2eaf6fede025..1c829bdf5889 100644 --- a/include/asm-s390/kvm_host.h +++ b/include/asm-s390/kvm_host.h @@ -128,6 +128,12 @@ struct kvm_vcpu_stat { u32 instruction_chsc; u32 instruction_stsi; u32 instruction_stfl; + u32 instruction_sigp_sense; + u32 instruction_sigp_emergency; + u32 instruction_sigp_stop; + u32 instruction_sigp_arch; + u32 instruction_sigp_prefix; + u32 instruction_sigp_restart; }; struct io_info { @@ -169,6 +175,10 @@ struct interrupt_info { }; }; +/* for local_interrupt.action_flags */ +#define ACTION_STORE_ON_STOP 1 +#define ACTION_STOP_ON_STOP 2 + struct local_interrupt { spinlock_t lock; struct list_head list; @@ -176,6 +186,8 @@ struct local_interrupt { struct float_interrupt *float_int; int timer_due; /* event indicator for waitqueue below */ wait_queue_head_t wq; + atomic_t *cpuflags; + unsigned int action_bits; }; struct float_interrupt { -- cgit v1.2.3 From e28acfea5dd9dbc67c2594cbefc140129dbd0e3f Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Tue, 25 Mar 2008 18:47:34 +0100 Subject: KVM: s390: intercepts for diagnose instructions This patch introduces interpretation of some diagnose instruction intercepts. Diagnose is our classic architected way of doing a hypercall. This patch features the following diagnose codes: - vm storage size, that tells the guest about its memory layout - time slice end, which is used by the guest to indicate that it waits for a lock and thus cannot use up its time slice in a useful way - ipl functions, which a guest can use to reset and reboot itself In order to implement ipl functions, we also introduce an exit reason that causes userspace to perform various resets on the virtual machine. All resets are described in the principles of operation book, except KVM_S390_RESET_IPL which causes a reboot of the machine. Acked-by: Martin Schwidefsky Signed-off-by: Christian Borntraeger Signed-off-by: Carsten Otte Signed-off-by: Avi Kivity --- include/asm-s390/kvm_host.h | 5 ++++- include/linux/kvm.h | 8 ++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-s390/kvm_host.h b/include/asm-s390/kvm_host.h index 1c829bdf5889..f8204a4f2e02 100644 --- a/include/asm-s390/kvm_host.h +++ b/include/asm-s390/kvm_host.h @@ -94,7 +94,9 @@ struct sie_block { psw_t gpsw; /* 0x0090 */ __u64 gg14; /* 0x00a0 */ __u64 gg15; /* 0x00a8 */ - __u8 reservedb0[80]; /* 0x00b0 */ + __u8 reservedb0[30]; /* 0x00b0 */ + __u16 iprcc; /* 0x00ce */ + __u8 reservedd0[48]; /* 0x00d0 */ __u64 gcr[16]; /* 0x0100 */ __u64 gbea; /* 0x0180 */ __u8 reserved188[120]; /* 0x0188 */ @@ -134,6 +136,7 @@ struct kvm_vcpu_stat { u32 instruction_sigp_arch; u32 instruction_sigp_prefix; u32 instruction_sigp_restart; + u32 diagnose_44; }; struct io_info { diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 029f0284a2fd..f04bb426618f 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -75,6 +75,7 @@ struct kvm_irqchip { #define KVM_EXIT_SET_TPR 11 #define KVM_EXIT_TPR_ACCESS 12 #define KVM_EXIT_S390_SIEIC 13 +#define KVM_EXIT_S390_RESET 14 /* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */ struct kvm_run { @@ -147,6 +148,13 @@ struct kvm_run { __u16 ipa; __u32 ipb; } s390_sieic; + /* KVM_EXIT_S390_RESET */ +#define KVM_S390_RESET_POR 1 +#define KVM_S390_RESET_CLEAR 2 +#define KVM_S390_RESET_SUBSYSTEM 4 +#define KVM_S390_RESET_CPU_INIT 8 +#define KVM_S390_RESET_IPL 16 + __u64 s390_reset_flags; /* Fix the size of the union. */ char padding[256]; }; -- cgit v1.2.3 From fa5877439d5a062d91c3abd5a690483bbdb4268e Mon Sep 17 00:00:00 2001 From: Carsten Otte Date: Tue, 25 Mar 2008 18:47:44 +0100 Subject: s390: KVM guest: detect when running on kvm This patch adds functionality to detect if the kernel runs under the KVM hypervisor. A macro MACHINE_IS_KVM is exported for device drivers. This allows drivers to skip device detection if the systems runs non-virtualized. We also define a preferred console to avoid having the ttyS0, which is a line mode only console. Signed-off-by: Christian Borntraeger Acked-by: Martin Schwidefsky Signed-off-by: Carsten Otte Signed-off-by: Avi Kivity --- include/asm-s390/setup.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-s390/setup.h b/include/asm-s390/setup.h index a76a6b8fd887..aaf4b518b940 100644 --- a/include/asm-s390/setup.h +++ b/include/asm-s390/setup.h @@ -62,6 +62,7 @@ extern unsigned long machine_flags; #define MACHINE_IS_VM (machine_flags & 1) #define MACHINE_IS_P390 (machine_flags & 4) #define MACHINE_HAS_MVPG (machine_flags & 16) +#define MACHINE_IS_KVM (machine_flags & 64) #define MACHINE_HAS_IDTE (machine_flags & 128) #define MACHINE_HAS_DIAG9C (machine_flags & 256) -- cgit v1.2.3 From e976a2b997fc4ad70ccc53acfe62811c4aaec851 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Tue, 25 Mar 2008 18:47:46 +0100 Subject: s390: KVM guest: virtio device support, and kvm hypercalls This patch implements kvm guest kernel support for paravirtualized devices and contains two parts: o a basic virtio stub using virtio_ring and external interrupts and hypercalls o full hypercall implementation in kvm_para.h Currently we dont have PCI on s390. Making virtio_pci usable for s390 seems more complicated that providing an own stub. This virtio stub is similar to the lguest one, the memory for the descriptors and the device detection is made via additional mapped memory on top of the guest storage. We use an external interrupt with extint code 0x2603 for host->guest notification. The hypercall definition uses the diag instruction for issuing a hypercall. The parameters are written in R2-R7, the hypercall number is written in R1. This is similar to the system call ABI (svc) which can use R1 for the number and R2-R6 for the parameters. Signed-off-by: Christian Borntraeger Acked-by: Martin Schwidefsky Signed-off-by: Carsten Otte Signed-off-by: Avi Kivity --- include/asm-s390/kvm_para.h | 124 +++++++++++++++++++++++++++++++++++++++++- include/asm-s390/kvm_virtio.h | 53 ++++++++++++++++++ 2 files changed, 175 insertions(+), 2 deletions(-) create mode 100644 include/asm-s390/kvm_virtio.h (limited to 'include') diff --git a/include/asm-s390/kvm_para.h b/include/asm-s390/kvm_para.h index e9bd3fbe878c..2c503796b619 100644 --- a/include/asm-s390/kvm_para.h +++ b/include/asm-s390/kvm_para.h @@ -14,14 +14,134 @@ #define __S390_KVM_PARA_H /* - * No hypercalls for KVM on s390 + * Hypercalls for KVM on s390. The calling convention is similar to the + * s390 ABI, so we use R2-R6 for parameters 1-5. In addition we use R1 + * as hypercall number and R7 as parameter 6. The return value is + * written to R2. We use the diagnose instruction as hypercall. To avoid + * conflicts with existing diagnoses for LPAR and z/VM, we do not use + * the instruction encoded number, but specify the number in R1 and + * use 0x500 as KVM hypercall + * + * Copyright IBM Corp. 2007,2008 + * Author(s): Christian Borntraeger + * + * This work is licensed under the terms of the GNU GPL, version 2. */ +static inline long kvm_hypercall0(unsigned long nr) +{ + register unsigned long __nr asm("1") = nr; + register long __rc asm("2"); + + asm volatile ("diag 2,4,0x500\n" + : "=d" (__rc) : "d" (__nr): "memory", "cc"); + return __rc; +} + +static inline long kvm_hypercall1(unsigned long nr, unsigned long p1) +{ + register unsigned long __nr asm("1") = nr; + register unsigned long __p1 asm("2") = p1; + register long __rc asm("2"); + + asm volatile ("diag 2,4,0x500\n" + : "=d" (__rc) : "d" (__nr), "0" (__p1) : "memory", "cc"); + return __rc; +} + +static inline long kvm_hypercall2(unsigned long nr, unsigned long p1, + unsigned long p2) +{ + register unsigned long __nr asm("1") = nr; + register unsigned long __p1 asm("2") = p1; + register unsigned long __p2 asm("3") = p2; + register long __rc asm("2"); + + asm volatile ("diag 2,4,0x500\n" + : "=d" (__rc) : "d" (__nr), "0" (__p1), "d" (__p2) + : "memory", "cc"); + return __rc; +} + +static inline long kvm_hypercall3(unsigned long nr, unsigned long p1, + unsigned long p2, unsigned long p3) +{ + register unsigned long __nr asm("1") = nr; + register unsigned long __p1 asm("2") = p1; + register unsigned long __p2 asm("3") = p2; + register unsigned long __p3 asm("4") = p3; + register long __rc asm("2"); + + asm volatile ("diag 2,4,0x500\n" + : "=d" (__rc) : "d" (__nr), "0" (__p1), "d" (__p2), + "d" (__p3) : "memory", "cc"); + return __rc; +} + + +static inline long kvm_hypercall4(unsigned long nr, unsigned long p1, + unsigned long p2, unsigned long p3, + unsigned long p4) +{ + register unsigned long __nr asm("1") = nr; + register unsigned long __p1 asm("2") = p1; + register unsigned long __p2 asm("3") = p2; + register unsigned long __p3 asm("4") = p3; + register unsigned long __p4 asm("5") = p4; + register long __rc asm("2"); + + asm volatile ("diag 2,4,0x500\n" + : "=d" (__rc) : "d" (__nr), "0" (__p1), "d" (__p2), + "d" (__p3), "d" (__p4) : "memory", "cc"); + return __rc; +} + +static inline long kvm_hypercall5(unsigned long nr, unsigned long p1, + unsigned long p2, unsigned long p3, + unsigned long p4, unsigned long p5) +{ + register unsigned long __nr asm("1") = nr; + register unsigned long __p1 asm("2") = p1; + register unsigned long __p2 asm("3") = p2; + register unsigned long __p3 asm("4") = p3; + register unsigned long __p4 asm("5") = p4; + register unsigned long __p5 asm("6") = p5; + register long __rc asm("2"); + + asm volatile ("diag 2,4,0x500\n" + : "=d" (__rc) : "d" (__nr), "0" (__p1), "d" (__p2), + "d" (__p3), "d" (__p4), "d" (__p5) : "memory", "cc"); + return __rc; +} + +static inline long kvm_hypercall6(unsigned long nr, unsigned long p1, + unsigned long p2, unsigned long p3, + unsigned long p4, unsigned long p5, + unsigned long p6) +{ + register unsigned long __nr asm("1") = nr; + register unsigned long __p1 asm("2") = p1; + register unsigned long __p2 asm("3") = p2; + register unsigned long __p3 asm("4") = p3; + register unsigned long __p4 asm("5") = p4; + register unsigned long __p5 asm("6") = p5; + register unsigned long __p6 asm("7") = p6; + register long __rc asm("2"); + + asm volatile ("diag 2,4,0x500\n" + : "=d" (__rc) : "d" (__nr), "0" (__p1), "d" (__p2), + "d" (__p3), "d" (__p4), "d" (__p5), "d" (__p6) + : "memory", "cc"); + return __rc; +} + +/* kvm on s390 is always paravirtualization enabled */ static inline int kvm_para_available(void) { - return 0; + return 1; } +/* No feature bits are currently assigned for kvm on s390 */ static inline unsigned int kvm_arch_para_features(void) { return 0; diff --git a/include/asm-s390/kvm_virtio.h b/include/asm-s390/kvm_virtio.h new file mode 100644 index 000000000000..5c871a990c29 --- /dev/null +++ b/include/asm-s390/kvm_virtio.h @@ -0,0 +1,53 @@ +/* + * kvm_virtio.h - definition for virtio for kvm on s390 + * + * Copyright IBM Corp. 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License (version 2 only) + * as published by the Free Software Foundation. + * + * Author(s): Christian Borntraeger + */ + +#ifndef __KVM_S390_VIRTIO_H +#define __KVM_S390_VIRTIO_H + +#include + +struct kvm_device_desc { + /* The device type: console, network, disk etc. Type 0 terminates. */ + __u8 type; + /* The number of virtqueues (first in config array) */ + __u8 num_vq; + /* + * The number of bytes of feature bits. Multiply by 2: one for host + * features and one for guest acknowledgements. + */ + __u8 feature_len; + /* The number of bytes of the config array after virtqueues. */ + __u8 config_len; + /* A status byte, written by the Guest. */ + __u8 status; + __u8 config[0]; +}; + +/* + * This is how we expect the device configuration field for a virtqueue + * to be laid out in config space. + */ +struct kvm_vqconfig { + /* The token returned with an interrupt. Set by the guest */ + __u64 token; + /* The address of the virtio ring */ + __u64 address; + /* The number of entries in the virtio_ring */ + __u16 num; + +}; + +#define KVM_S390_VIRTIO_NOTIFY 0 +#define KVM_S390_VIRTIO_RESET 1 +#define KVM_S390_VIRTIO_SET_STATUS 2 + +#endif -- cgit v1.2.3 From 3200f405a1e8e06c8634f11d33614455baa4e6be Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Sat, 29 Mar 2008 20:17:59 -0300 Subject: KVM: MMU: unify slots_lock usage Unify slots_lock acquision around vcpu_run(). This is simpler and less error-prone. Also fix some callsites that were not grabbing the lock properly. [avi: drop slots_lock while in guest mode to avoid holding the lock for indefinite periods] Signed-off-by: Marcelo Tosatti Signed-off-by: Avi Kivity --- include/asm-x86/kvm_host.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 7b28cf949d55..2b081ed44fdb 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -446,7 +446,7 @@ void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages); int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3); -int __emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, +int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, const void *val, int bytes); int kvm_pv_mmu_op(struct kvm_vcpu *vcpu, unsigned long bytes, gpa_t addr, unsigned long *ret); -- cgit v1.2.3 From 9c20456a32ce9e82ccda55e12c10016b181d85e5 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Tue, 1 Apr 2008 16:44:56 +0200 Subject: KVM: function declaration parameter name cleanup The kvm_host.h file for x86 declares the functions kvm_set_cr[0348]. In the header file their second parameter is named cr0 in all cases. This patch renames the parameters so that they match the function name. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- include/asm-x86/kvm_host.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 2b081ed44fdb..b9230490d777 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -495,9 +495,9 @@ int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason); void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0); -void kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr0); -void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr0); -void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr0); +void kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3); +void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); +void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8); unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu); void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw); void kvm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l); -- cgit v1.2.3 From d39f13b0da7fa7f705fbe6c80995205d0380bc7a Mon Sep 17 00:00:00 2001 From: Izik Eidus Date: Sun, 30 Mar 2008 16:01:25 +0300 Subject: KVM: add vm refcounting the main purpose of adding this functions is the abilaty to release the spinlock that protect the kvm list while still be able to do operations on a specific kvm in a safe way. Signed-off-by: Izik Eidus Signed-off-by: Avi Kivity --- include/linux/kvm_host.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index f4e143621e35..a2ceb51b4274 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -114,6 +114,7 @@ struct kvm { struct kvm_io_bus pio_bus; struct kvm_vm_stat stat; struct kvm_arch arch; + atomic_t users_count; }; /* The guest did something we don't support. */ @@ -140,6 +141,9 @@ int kvm_init(void *opaque, unsigned int vcpu_size, struct module *module); void kvm_exit(void); +void kvm_get_kvm(struct kvm *kvm); +void kvm_put_kvm(struct kvm *kvm); + #define HPA_MSB ((sizeof(hpa_t) * 8) - 1) #define HPA_ERR_MASK ((hpa_t)1 << HPA_MSB) static inline int is_error_hpa(hpa_t hpa) { return hpa >> HPA_MSB; } -- cgit v1.2.3 From c71799c1f404c6e4f34fa64e6be39cd6149e5019 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 4 Apr 2008 16:03:34 +0200 Subject: KVM: s390: Improve pgste accesses There is no need to use interlocked updates when the rcp lock is held. Therefore the simple bitops variants can be used. This should improve performance. Signed-off-by: Heiko Carstens Signed-off-by: Carsten Otte Signed-off-by: Avi Kivity --- include/asm-s390/pgtable.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h index 7fe5c4b6d82d..4c0698c0dda5 100644 --- a/include/asm-s390/pgtable.h +++ b/include/asm-s390/pgtable.h @@ -553,12 +553,12 @@ static inline void ptep_rcp_copy(pte_t *ptep) skey = page_get_storage_key(page_to_phys(page)); if (skey & _PAGE_CHANGED) - set_bit(RCP_GC_BIT, pgste); + set_bit_simple(RCP_GC_BIT, pgste); if (skey & _PAGE_REFERENCED) - set_bit(RCP_GR_BIT, pgste); - if (test_and_clear_bit(RCP_HC_BIT, pgste)) + set_bit_simple(RCP_GR_BIT, pgste); + if (test_and_clear_bit_simple(RCP_HC_BIT, pgste)) SetPageDirty(page); - if (test_and_clear_bit(RCP_HR_BIT, pgste)) + if (test_and_clear_bit_simple(RCP_HR_BIT, pgste)) SetPageReferenced(page); #endif } @@ -732,8 +732,8 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, young = ((page_get_storage_key(physpage) & _PAGE_REFERENCED) != 0); rcp_lock(ptep); if (young) - set_bit(RCP_GR_BIT, pgste); - young |= test_and_clear_bit(RCP_HR_BIT, pgste); + set_bit_simple(RCP_GR_BIT, pgste); + young |= test_and_clear_bit_simple(RCP_HR_BIT, pgste); rcp_unlock(ptep); return young; #endif -- cgit v1.2.3 From e235f3450f5bf94b989746163b7791784a78ee05 Mon Sep 17 00:00:00 2001 From: Xiantao Zhang Date: Tue, 1 Apr 2008 14:42:00 +0800 Subject: KVM: ia64: Prepare some structure and routines for kvm use Register structures are defined per SDM. Add three small routines for kernel: ia64_ttag, ia64_loadrs, ia64_flushrs Signed-off-by: Xiantao Zhang Signed-off-by: Avi Kivity --- include/asm-ia64/gcc_intrin.h | 12 +++++++++ include/asm-ia64/processor.h | 63 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) (limited to 'include') diff --git a/include/asm-ia64/gcc_intrin.h b/include/asm-ia64/gcc_intrin.h index de2ed2cbdd84..2fe292c275fe 100644 --- a/include/asm-ia64/gcc_intrin.h +++ b/include/asm-ia64/gcc_intrin.h @@ -21,6 +21,10 @@ #define ia64_invala_fr(regnum) asm volatile ("invala.e f%0" :: "i"(regnum)) +#define ia64_flushrs() asm volatile ("flushrs;;":::"memory") + +#define ia64_loadrs() asm volatile ("loadrs;;":::"memory") + extern void ia64_bad_param_for_setreg (void); extern void ia64_bad_param_for_getreg (void); @@ -517,6 +521,14 @@ do { \ #define ia64_ptrd(addr, size) \ asm volatile ("ptr.d %0,%1" :: "r"(addr), "r"(size) : "memory") +#define ia64_ttag(addr) \ +({ \ + __u64 ia64_intri_res; \ + asm volatile ("ttag %0=%1" : "=r"(ia64_intri_res) : "r" (addr)); \ + ia64_intri_res; \ +}) + + /* Values for lfhint in ia64_lfetch and ia64_lfetch_fault */ #define ia64_lfhint_none 0 diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h index 741f7ecb986a..6aff126fc07e 100644 --- a/include/asm-ia64/processor.h +++ b/include/asm-ia64/processor.h @@ -119,6 +119,69 @@ struct ia64_psr { __u64 reserved4 : 19; }; +union ia64_isr { + __u64 val; + struct { + __u64 code : 16; + __u64 vector : 8; + __u64 reserved1 : 8; + __u64 x : 1; + __u64 w : 1; + __u64 r : 1; + __u64 na : 1; + __u64 sp : 1; + __u64 rs : 1; + __u64 ir : 1; + __u64 ni : 1; + __u64 so : 1; + __u64 ei : 2; + __u64 ed : 1; + __u64 reserved2 : 20; + }; +}; + +union ia64_lid { + __u64 val; + struct { + __u64 rv : 16; + __u64 eid : 8; + __u64 id : 8; + __u64 ig : 32; + }; +}; + +union ia64_tpr { + __u64 val; + struct { + __u64 ig0 : 4; + __u64 mic : 4; + __u64 rsv : 8; + __u64 mmi : 1; + __u64 ig1 : 47; + }; +}; + +union ia64_itir { + __u64 val; + struct { + __u64 rv3 : 2; /* 0-1 */ + __u64 ps : 6; /* 2-7 */ + __u64 key : 24; /* 8-31 */ + __u64 rv4 : 32; /* 32-63 */ + }; +}; + +union ia64_rr { + __u64 val; + struct { + __u64 ve : 1; /* enable hw walker */ + __u64 reserved0: 1; /* reserved */ + __u64 ps : 6; /* log page size */ + __u64 rid : 24; /* region id */ + __u64 reserved1: 32; /* reserved */ + }; +}; + /* * CPU type, hardware bug flags, and per-CPU state. Frequently used * state comes earlier: -- cgit v1.2.3 From 1a9c1ac46990194f6b6ddc591c24e385e611fa25 Mon Sep 17 00:00:00 2001 From: Xiantao Zhang Date: Tue, 1 Apr 2008 14:45:06 +0800 Subject: KVM: ia64: Add header files for kvm/ia64 Three header files are added: asm-ia64/kvm.h asm-ia64/kvm_host.h asm-ia64/kvm_para.h Signed-off-by: Xiantao Zhang Signed-off-by: Avi Kivity --- include/asm-ia64/kvm.h | 205 ++++++++++++++++- include/asm-ia64/kvm_host.h | 524 ++++++++++++++++++++++++++++++++++++++++++++ include/asm-ia64/kvm_para.h | 29 +++ 3 files changed, 755 insertions(+), 3 deletions(-) create mode 100644 include/asm-ia64/kvm_host.h create mode 100644 include/asm-ia64/kvm_para.h (limited to 'include') diff --git a/include/asm-ia64/kvm.h b/include/asm-ia64/kvm.h index 030d29b4b26b..eb2d3559d089 100644 --- a/include/asm-ia64/kvm.h +++ b/include/asm-ia64/kvm.h @@ -1,6 +1,205 @@ -#ifndef __LINUX_KVM_IA64_H -#define __LINUX_KVM_IA64_H +#ifndef __ASM_IA64_KVM_H +#define __ASM_IA64_KVM_H -/* ia64 does not support KVM */ +/* + * asm-ia64/kvm.h: kvm structure definitions for ia64 + * + * Copyright (C) 2007 Xiantao Zhang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + */ + +#include +#include + +#include + +/* Architectural interrupt line count. */ +#define KVM_NR_INTERRUPTS 256 + +#define KVM_IOAPIC_NUM_PINS 24 + +struct kvm_ioapic_state { + __u64 base_address; + __u32 ioregsel; + __u32 id; + __u32 irr; + __u32 pad; + union { + __u64 bits; + struct { + __u8 vector; + __u8 delivery_mode:3; + __u8 dest_mode:1; + __u8 delivery_status:1; + __u8 polarity:1; + __u8 remote_irr:1; + __u8 trig_mode:1; + __u8 mask:1; + __u8 reserve:7; + __u8 reserved[4]; + __u8 dest_id; + } fields; + } redirtbl[KVM_IOAPIC_NUM_PINS]; +}; + +#define KVM_IRQCHIP_PIC_MASTER 0 +#define KVM_IRQCHIP_PIC_SLAVE 1 +#define KVM_IRQCHIP_IOAPIC 2 + +#define KVM_CONTEXT_SIZE 8*1024 + +union context { + /* 8K size */ + char dummy[KVM_CONTEXT_SIZE]; + struct { + unsigned long psr; + unsigned long pr; + unsigned long caller_unat; + unsigned long pad; + unsigned long gr[32]; + unsigned long ar[128]; + unsigned long br[8]; + unsigned long cr[128]; + unsigned long rr[8]; + unsigned long ibr[8]; + unsigned long dbr[8]; + unsigned long pkr[8]; + struct ia64_fpreg fr[128]; + }; +}; + +struct thash_data { + union { + struct { + unsigned long p : 1; /* 0 */ + unsigned long rv1 : 1; /* 1 */ + unsigned long ma : 3; /* 2-4 */ + unsigned long a : 1; /* 5 */ + unsigned long d : 1; /* 6 */ + unsigned long pl : 2; /* 7-8 */ + unsigned long ar : 3; /* 9-11 */ + unsigned long ppn : 38; /* 12-49 */ + unsigned long rv2 : 2; /* 50-51 */ + unsigned long ed : 1; /* 52 */ + unsigned long ig1 : 11; /* 53-63 */ + }; + struct { + unsigned long __rv1 : 53; /* 0-52 */ + unsigned long contiguous : 1; /*53 */ + unsigned long tc : 1; /* 54 TR or TC */ + unsigned long cl : 1; + /* 55 I side or D side cache line */ + unsigned long len : 4; /* 56-59 */ + unsigned long io : 1; /* 60 entry is for io or not */ + unsigned long nomap : 1; + /* 61 entry cann't be inserted into machine TLB.*/ + unsigned long checked : 1; + /* 62 for VTLB/VHPT sanity check */ + unsigned long invalid : 1; + /* 63 invalid entry */ + }; + unsigned long page_flags; + }; /* same for VHPT and TLB */ + + union { + struct { + unsigned long rv3 : 2; + unsigned long ps : 6; + unsigned long key : 24; + unsigned long rv4 : 32; + }; + unsigned long itir; + }; + union { + struct { + unsigned long ig2 : 12; + unsigned long vpn : 49; + unsigned long vrn : 3; + }; + unsigned long ifa; + unsigned long vadr; + struct { + unsigned long tag : 63; + unsigned long ti : 1; + }; + unsigned long etag; + }; + union { + struct thash_data *next; + unsigned long rid; + unsigned long gpaddr; + }; +}; + +#define NITRS 8 +#define NDTRS 8 + +struct saved_vpd { + unsigned long vhpi; + unsigned long vgr[16]; + unsigned long vbgr[16]; + unsigned long vnat; + unsigned long vbnat; + unsigned long vcpuid[5]; + unsigned long vpsr; + unsigned long vpr; + unsigned long vcr[128]; +}; + +struct kvm_regs { + char *saved_guest; + char *saved_stack; + struct saved_vpd vpd; + /*Arch-regs*/ + int mp_state; + unsigned long vmm_rr; + /* TR and TC. */ + struct thash_data itrs[NITRS]; + struct thash_data dtrs[NDTRS]; + /* Bit is set if there is a tr/tc for the region. */ + unsigned char itr_regions; + unsigned char dtr_regions; + unsigned char tc_regions; + + char irq_check; + unsigned long saved_itc; + unsigned long itc_check; + unsigned long timer_check; + unsigned long timer_pending; + unsigned long last_itc; + + unsigned long vrr[8]; + unsigned long ibr[8]; + unsigned long dbr[8]; + unsigned long insvc[4]; /* Interrupt in service. */ + unsigned long xtp; + + unsigned long metaphysical_rr0; /* from kvm_arch (so is pinned) */ + unsigned long metaphysical_rr4; /* from kvm_arch (so is pinned) */ + unsigned long metaphysical_saved_rr0; /* from kvm_arch */ + unsigned long metaphysical_saved_rr4; /* from kvm_arch */ + unsigned long fp_psr; /*used for lazy float register */ + unsigned long saved_gp; + /*for phycial emulation */ +}; + +struct kvm_sregs { +}; + +struct kvm_fpu { +}; #endif diff --git a/include/asm-ia64/kvm_host.h b/include/asm-ia64/kvm_host.h new file mode 100644 index 000000000000..d6d6e15c1924 --- /dev/null +++ b/include/asm-ia64/kvm_host.h @@ -0,0 +1,524 @@ +/* + * kvm_host.h: used for kvm module, and hold ia64-specific sections. + * + * Copyright (C) 2007, Intel Corporation. + * + * Xiantao Zhang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + */ + +#ifndef __ASM_KVM_HOST_H +#define __ASM_KVM_HOST_H + + +#include +#include +#include +#include +#include + +#include +#include + +#define KVM_MAX_VCPUS 4 +#define KVM_MEMORY_SLOTS 32 +/* memory slots that does not exposed to userspace */ +#define KVM_PRIVATE_MEM_SLOTS 4 + + +/* define exit reasons from vmm to kvm*/ +#define EXIT_REASON_VM_PANIC 0 +#define EXIT_REASON_MMIO_INSTRUCTION 1 +#define EXIT_REASON_PAL_CALL 2 +#define EXIT_REASON_SAL_CALL 3 +#define EXIT_REASON_SWITCH_RR6 4 +#define EXIT_REASON_VM_DESTROY 5 +#define EXIT_REASON_EXTERNAL_INTERRUPT 6 +#define EXIT_REASON_IPI 7 +#define EXIT_REASON_PTC_G 8 + +/*Define vmm address space and vm data space.*/ +#define KVM_VMM_SIZE (16UL<<20) +#define KVM_VMM_SHIFT 24 +#define KVM_VMM_BASE 0xD000000000000000UL +#define VMM_SIZE (8UL<<20) + +/* + * Define vm_buffer, used by PAL Services, base address. + * Note: vmbuffer is in the VMM-BLOCK, the size must be < 8M + */ +#define KVM_VM_BUFFER_BASE (KVM_VMM_BASE + VMM_SIZE) +#define KVM_VM_BUFFER_SIZE (8UL<<20) + +/*Define Virtual machine data layout.*/ +#define KVM_VM_DATA_SHIFT 24 +#define KVM_VM_DATA_SIZE (1UL << KVM_VM_DATA_SHIFT) +#define KVM_VM_DATA_BASE (KVM_VMM_BASE + KVM_VMM_SIZE) + + +#define KVM_P2M_BASE KVM_VM_DATA_BASE +#define KVM_P2M_OFS 0 +#define KVM_P2M_SIZE (8UL << 20) + +#define KVM_VHPT_BASE (KVM_P2M_BASE + KVM_P2M_SIZE) +#define KVM_VHPT_OFS KVM_P2M_SIZE +#define KVM_VHPT_BLOCK_SIZE (2UL << 20) +#define VHPT_SHIFT 18 +#define VHPT_SIZE (1UL << VHPT_SHIFT) +#define VHPT_NUM_ENTRIES (1<<(VHPT_SHIFT-5)) + +#define KVM_VTLB_BASE (KVM_VHPT_BASE+KVM_VHPT_BLOCK_SIZE) +#define KVM_VTLB_OFS (KVM_VHPT_OFS+KVM_VHPT_BLOCK_SIZE) +#define KVM_VTLB_BLOCK_SIZE (1UL<<20) +#define VTLB_SHIFT 17 +#define VTLB_SIZE (1UL<vcpu_id) << 24) + +/* + *Delivery mode + */ +#define SAPIC_DELIV_SHIFT 8 +#define SAPIC_FIXED 0x0 +#define SAPIC_LOWEST_PRIORITY 0x1 +#define SAPIC_PMI 0x2 +#define SAPIC_NMI 0x4 +#define SAPIC_INIT 0x5 +#define SAPIC_EXTINT 0x7 + +/* + * vcpu->requests bit members for arch + */ +#define KVM_REQ_PTC_G 32 +#define KVM_REQ_RESUME 33 + +#define KVM_PAGES_PER_HPAGE 1 + +struct kvm; +struct kvm_vcpu; +struct kvm_guest_debug{ +}; + +struct kvm_mmio_req { + uint64_t addr; /* physical address */ + uint64_t size; /* size in bytes */ + uint64_t data; /* data (or paddr of data) */ + uint8_t state:4; + uint8_t dir:1; /* 1=read, 0=write */ +}; + +/*Pal data struct */ +struct kvm_pal_call{ + /*In area*/ + uint64_t gr28; + uint64_t gr29; + uint64_t gr30; + uint64_t gr31; + /*Out area*/ + struct ia64_pal_retval ret; +}; + +/* Sal data structure */ +struct kvm_sal_call{ + /*In area*/ + uint64_t in0; + uint64_t in1; + uint64_t in2; + uint64_t in3; + uint64_t in4; + uint64_t in5; + uint64_t in6; + uint64_t in7; + struct sal_ret_values ret; +}; + +/*Guest change rr6*/ +struct kvm_switch_rr6 { + uint64_t old_rr; + uint64_t new_rr; +}; + +union ia64_ipi_a{ + unsigned long val; + struct { + unsigned long rv : 3; + unsigned long ir : 1; + unsigned long eid : 8; + unsigned long id : 8; + unsigned long ib_base : 44; + }; +}; + +union ia64_ipi_d { + unsigned long val; + struct { + unsigned long vector : 8; + unsigned long dm : 3; + unsigned long ig : 53; + }; +}; + +/*ipi check exit data*/ +struct kvm_ipi_data{ + union ia64_ipi_a addr; + union ia64_ipi_d data; +}; + +/*global purge data*/ +struct kvm_ptc_g { + unsigned long vaddr; + unsigned long rr; + unsigned long ps; + struct kvm_vcpu *vcpu; +}; + +/*Exit control data */ +struct exit_ctl_data{ + uint32_t exit_reason; + uint32_t vm_status; + union { + struct kvm_mmio_req ioreq; + struct kvm_pal_call pal_data; + struct kvm_sal_call sal_data; + struct kvm_switch_rr6 rr_data; + struct kvm_ipi_data ipi_data; + struct kvm_ptc_g ptc_g_data; + } u; +}; + +union pte_flags { + unsigned long val; + struct { + unsigned long p : 1; /*0 */ + unsigned long : 1; /* 1 */ + unsigned long ma : 3; /* 2-4 */ + unsigned long a : 1; /* 5 */ + unsigned long d : 1; /* 6 */ + unsigned long pl : 2; /* 7-8 */ + unsigned long ar : 3; /* 9-11 */ + unsigned long ppn : 38; /* 12-49 */ + unsigned long : 2; /* 50-51 */ + unsigned long ed : 1; /* 52 */ + }; +}; + +union ia64_pta { + unsigned long val; + struct { + unsigned long ve : 1; + unsigned long reserved0 : 1; + unsigned long size : 6; + unsigned long vf : 1; + unsigned long reserved1 : 6; + unsigned long base : 49; + }; +}; + +struct thash_cb { + /* THASH base information */ + struct thash_data *hash; /* hash table pointer */ + union ia64_pta pta; + int num; +}; + +struct kvm_vcpu_stat { +}; + +struct kvm_vcpu_arch { + int launched; + int last_exit; + int last_run_cpu; + int vmm_tr_slot; + int vm_tr_slot; + +#define VCPU_MP_STATE_RUNNABLE 0 +#define VCPU_MP_STATE_UNINITIALIZED 1 +#define VCPU_MP_STATE_INIT_RECEIVED 2 +#define VCPU_MP_STATE_HALTED 3 + int mp_state; + +#define MAX_PTC_G_NUM 3 + int ptc_g_count; + struct kvm_ptc_g ptc_g_data[MAX_PTC_G_NUM]; + + /*halt timer to wake up sleepy vcpus*/ + struct hrtimer hlt_timer; + long ht_active; + + struct kvm_lapic *apic; /* kernel irqchip context */ + struct vpd *vpd; + + /* Exit data for vmm_transition*/ + struct exit_ctl_data exit_data; + + cpumask_t cache_coherent_map; + + unsigned long vmm_rr; + unsigned long host_rr6; + unsigned long psbits[8]; + unsigned long cr_iipa; + unsigned long cr_isr; + unsigned long vsa_base; + unsigned long dirty_log_lock_pa; + unsigned long __gp; + /* TR and TC. */ + struct thash_data itrs[NITRS]; + struct thash_data dtrs[NDTRS]; + /* Bit is set if there is a tr/tc for the region. */ + unsigned char itr_regions; + unsigned char dtr_regions; + unsigned char tc_regions; + /* purge all */ + unsigned long ptce_base; + unsigned long ptce_count[2]; + unsigned long ptce_stride[2]; + /* itc/itm */ + unsigned long last_itc; + long itc_offset; + unsigned long itc_check; + unsigned long timer_check; + unsigned long timer_pending; + + unsigned long vrr[8]; + unsigned long ibr[8]; + unsigned long dbr[8]; + unsigned long insvc[4]; /* Interrupt in service. */ + unsigned long xtp; + + unsigned long metaphysical_rr0; /* from kvm_arch (so is pinned) */ + unsigned long metaphysical_rr4; /* from kvm_arch (so is pinned) */ + unsigned long metaphysical_saved_rr0; /* from kvm_arch */ + unsigned long metaphysical_saved_rr4; /* from kvm_arch */ + unsigned long fp_psr; /*used for lazy float register */ + unsigned long saved_gp; + /*for phycial emulation */ + int mode_flags; + struct thash_cb vtlb; + struct thash_cb vhpt; + char irq_check; + char irq_new_pending; + + unsigned long opcode; + unsigned long cause; + union context host; + union context guest; +}; + +struct kvm_vm_stat { + u64 remote_tlb_flush; +}; + +struct kvm_sal_data { + unsigned long boot_ip; + unsigned long boot_gp; +}; + +struct kvm_arch { + unsigned long vm_base; + unsigned long metaphysical_rr0; + unsigned long metaphysical_rr4; + unsigned long vmm_init_rr; + unsigned long vhpt_base; + unsigned long vtlb_base; + unsigned long vpd_base; + spinlock_t dirty_log_lock; + struct kvm_ioapic *vioapic; + struct kvm_vm_stat stat; + struct kvm_sal_data rdv_sal_data; +}; + +union cpuid3_t { + u64 value; + struct { + u64 number : 8; + u64 revision : 8; + u64 model : 8; + u64 family : 8; + u64 archrev : 8; + u64 rv : 24; + }; +}; + +struct kvm_pt_regs { + /* The following registers are saved by SAVE_MIN: */ + unsigned long b6; /* scratch */ + unsigned long b7; /* scratch */ + + unsigned long ar_csd; /* used by cmp8xchg16 (scratch) */ + unsigned long ar_ssd; /* reserved for future use (scratch) */ + + unsigned long r8; /* scratch (return value register 0) */ + unsigned long r9; /* scratch (return value register 1) */ + unsigned long r10; /* scratch (return value register 2) */ + unsigned long r11; /* scratch (return value register 3) */ + + unsigned long cr_ipsr; /* interrupted task's psr */ + unsigned long cr_iip; /* interrupted task's instruction pointer */ + unsigned long cr_ifs; /* interrupted task's function state */ + + unsigned long ar_unat; /* interrupted task's NaT register (preserved) */ + unsigned long ar_pfs; /* prev function state */ + unsigned long ar_rsc; /* RSE configuration */ + /* The following two are valid only if cr_ipsr.cpl > 0: */ + unsigned long ar_rnat; /* RSE NaT */ + unsigned long ar_bspstore; /* RSE bspstore */ + + unsigned long pr; /* 64 predicate registers (1 bit each) */ + unsigned long b0; /* return pointer (bp) */ + unsigned long loadrs; /* size of dirty partition << 16 */ + + unsigned long r1; /* the gp pointer */ + unsigned long r12; /* interrupted task's memory stack pointer */ + unsigned long r13; /* thread pointer */ + + unsigned long ar_fpsr; /* floating point status (preserved) */ + unsigned long r15; /* scratch */ + + /* The remaining registers are NOT saved for system calls. */ + unsigned long r14; /* scratch */ + unsigned long r2; /* scratch */ + unsigned long r3; /* scratch */ + unsigned long r16; /* scratch */ + unsigned long r17; /* scratch */ + unsigned long r18; /* scratch */ + unsigned long r19; /* scratch */ + unsigned long r20; /* scratch */ + unsigned long r21; /* scratch */ + unsigned long r22; /* scratch */ + unsigned long r23; /* scratch */ + unsigned long r24; /* scratch */ + unsigned long r25; /* scratch */ + unsigned long r26; /* scratch */ + unsigned long r27; /* scratch */ + unsigned long r28; /* scratch */ + unsigned long r29; /* scratch */ + unsigned long r30; /* scratch */ + unsigned long r31; /* scratch */ + unsigned long ar_ccv; /* compare/exchange value (scratch) */ + + /* + * Floating point registers that the kernel considers scratch: + */ + struct ia64_fpreg f6; /* scratch */ + struct ia64_fpreg f7; /* scratch */ + struct ia64_fpreg f8; /* scratch */ + struct ia64_fpreg f9; /* scratch */ + struct ia64_fpreg f10; /* scratch */ + struct ia64_fpreg f11; /* scratch */ + + unsigned long r4; /* preserved */ + unsigned long r5; /* preserved */ + unsigned long r6; /* preserved */ + unsigned long r7; /* preserved */ + unsigned long eml_unat; /* used for emulating instruction */ + unsigned long pad0; /* alignment pad */ +}; + +static inline struct kvm_pt_regs *vcpu_regs(struct kvm_vcpu *v) +{ + return (struct kvm_pt_regs *) ((unsigned long) v + IA64_STK_OFFSET) - 1; +} + +typedef int kvm_vmm_entry(void); +typedef void kvm_tramp_entry(union context *host, union context *guest); + +struct kvm_vmm_info{ + struct module *module; + kvm_vmm_entry *vmm_entry; + kvm_tramp_entry *tramp_entry; + unsigned long vmm_ivt; +}; + +int kvm_highest_pending_irq(struct kvm_vcpu *vcpu); +int kvm_emulate_halt(struct kvm_vcpu *vcpu); +int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run); +void kvm_sal_emul(struct kvm_vcpu *vcpu); + +#endif diff --git a/include/asm-ia64/kvm_para.h b/include/asm-ia64/kvm_para.h new file mode 100644 index 000000000000..9f9796bb3441 --- /dev/null +++ b/include/asm-ia64/kvm_para.h @@ -0,0 +1,29 @@ +#ifndef __IA64_KVM_PARA_H +#define __IA64_KVM_PARA_H + +/* + * asm-ia64/kvm_para.h + * + * Copyright (C) 2007 Xiantao Zhang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + */ + +static inline unsigned int kvm_arch_para_features(void) +{ + return 0; +} + +#endif -- cgit v1.2.3 From 35149e2129fe34fc8cb5917e1ecf5156b0fa3415 Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Wed, 2 Apr 2008 14:46:56 -0500 Subject: KVM: MMU: Don't assume struct page for x86 This patch introduces a gfn_to_pfn() function and corresponding functions like kvm_release_pfn_dirty(). Using these new functions, we can modify the x86 MMU to no longer assume that it can always get a struct page for any given gfn. We don't want to eliminate gfn_to_page() entirely because a number of places assume they can do gfn_to_page() and then kmap() the results. When we support IO memory, gfn_to_page() will fail for IO pages although gfn_to_pfn() will succeed. This does not implement support for avoiding reference counting for reserved RAM or for IO memory. However, it should make those things pretty straight forward. Since we're only introducing new common symbols, I don't think it will break the non-x86 architectures but I haven't tested those. I've tested Intel, AMD, NPT, and hugetlbfs with Windows and Linux guests. [avi: fix overflow when shifting left pfns by adding casts] Signed-off-by: Anthony Liguori Signed-off-by: Avi Kivity --- include/asm-x86/kvm_host.h | 4 ++-- include/linux/kvm_host.h | 12 ++++++++++++ include/linux/kvm_types.h | 2 ++ 3 files changed, 16 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index b9230490d777..de3eccfb767c 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -248,8 +248,8 @@ struct kvm_vcpu_arch { u64 *last_pte_updated; struct { - gfn_t gfn; /* presumed gfn during guest pte update */ - struct page *page; /* page corresponding to that gfn */ + gfn_t gfn; /* presumed gfn during guest pte update */ + pfn_t pfn; /* pfn corresponding to that gfn */ int largepage; } update_pte; diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index a2ceb51b4274..578c3638bbba 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -150,8 +150,10 @@ static inline int is_error_hpa(hpa_t hpa) { return hpa >> HPA_MSB; } struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva); extern struct page *bad_page; +extern pfn_t bad_pfn; int is_error_page(struct page *page); +int is_error_pfn(pfn_t pfn); int kvm_is_error_hva(unsigned long addr); int kvm_set_memory_region(struct kvm *kvm, struct kvm_userspace_memory_region *mem, @@ -168,6 +170,16 @@ struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn); unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn); void kvm_release_page_clean(struct page *page); void kvm_release_page_dirty(struct page *page); +void kvm_set_page_dirty(struct page *page); +void kvm_set_page_accessed(struct page *page); + +pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn); +void kvm_release_pfn_dirty(pfn_t); +void kvm_release_pfn_clean(pfn_t pfn); +void kvm_set_pfn_dirty(pfn_t pfn); +void kvm_set_pfn_accessed(pfn_t pfn); +void kvm_get_pfn(pfn_t pfn); + int kvm_read_guest_page(struct kvm *kvm, gfn_t gfn, void *data, int offset, int len); int kvm_read_guest_atomic(struct kvm *kvm, gpa_t gpa, void *data, diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h index 1c4e46decb22..9b6f395c9625 100644 --- a/include/linux/kvm_types.h +++ b/include/linux/kvm_types.h @@ -38,6 +38,8 @@ typedef unsigned long hva_t; typedef u64 hpa_t; typedef unsigned long hfn_t; +typedef hfn_t pfn_t; + struct kvm_pio_request { unsigned long count; int cur_count; -- cgit v1.2.3 From 53371b5098543ab09dcb0c7ce31da887dbe58c62 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 9 Apr 2008 14:15:30 +0200 Subject: KVM: SVM: add intercept for machine check exception To properly forward a MCE occured while the guest is running to the host, we have to intercept this exception and call the host handler by hand. This is implemented by this patch. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- include/asm-x86/kvm_host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index de3eccfb767c..286117878ce2 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -62,6 +62,7 @@ #define SS_VECTOR 12 #define GP_VECTOR 13 #define PF_VECTOR 14 +#define MC_VECTOR 18 #define SELECTOR_TI_MASK (1 << 2) #define SELECTOR_RPL_MASK 0x03 -- cgit v1.2.3 From 2714d1d3d6be882b97cd0125140fccf9976a460a Mon Sep 17 00:00:00 2001 From: "Feng (Eric) Liu" Date: Thu, 10 Apr 2008 15:31:10 -0400 Subject: KVM: Add trace markers Trace markers allow userspace to trace execution of a virtual machine in order to monitor its performance. Signed-off-by: Feng (Eric) Liu Signed-off-by: Avi Kivity --- include/asm-x86/kvm.h | 20 +++++++++++++++++++ include/asm-x86/kvm_host.h | 19 ++++++++++++++++++ include/linux/kvm.h | 49 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 87 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-x86/kvm.h b/include/asm-x86/kvm.h index 12b4b25371d5..80eefef2cc76 100644 --- a/include/asm-x86/kvm.h +++ b/include/asm-x86/kvm.h @@ -209,4 +209,24 @@ struct kvm_pit_state { struct kvm_pit_channel_state channels[3]; }; +#define KVM_TRC_INJ_VIRQ (KVM_TRC_HANDLER + 0x02) +#define KVM_TRC_REDELIVER_EVT (KVM_TRC_HANDLER + 0x03) +#define KVM_TRC_PEND_INTR (KVM_TRC_HANDLER + 0x04) +#define KVM_TRC_IO_READ (KVM_TRC_HANDLER + 0x05) +#define KVM_TRC_IO_WRITE (KVM_TRC_HANDLER + 0x06) +#define KVM_TRC_CR_READ (KVM_TRC_HANDLER + 0x07) +#define KVM_TRC_CR_WRITE (KVM_TRC_HANDLER + 0x08) +#define KVM_TRC_DR_READ (KVM_TRC_HANDLER + 0x09) +#define KVM_TRC_DR_WRITE (KVM_TRC_HANDLER + 0x0A) +#define KVM_TRC_MSR_READ (KVM_TRC_HANDLER + 0x0B) +#define KVM_TRC_MSR_WRITE (KVM_TRC_HANDLER + 0x0C) +#define KVM_TRC_CPUID (KVM_TRC_HANDLER + 0x0D) +#define KVM_TRC_INTR (KVM_TRC_HANDLER + 0x0E) +#define KVM_TRC_NMI (KVM_TRC_HANDLER + 0x0F) +#define KVM_TRC_VMMCALL (KVM_TRC_HANDLER + 0x10) +#define KVM_TRC_HLT (KVM_TRC_HANDLER + 0x11) +#define KVM_TRC_CLTS (KVM_TRC_HANDLER + 0x12) +#define KVM_TRC_LMSW (KVM_TRC_HANDLER + 0x13) +#define KVM_TRC_APIC_ACCESS (KVM_TRC_HANDLER + 0x14) + #endif diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 286117878ce2..15169cb71c83 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -667,4 +667,23 @@ enum { TASK_SWITCH_GATE = 3, }; +#define KVMTRACE_5D(evt, vcpu, d1, d2, d3, d4, d5, name) \ + trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \ + vcpu, 5, d1, d2, d3, d4, d5) +#define KVMTRACE_4D(evt, vcpu, d1, d2, d3, d4, name) \ + trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \ + vcpu, 4, d1, d2, d3, d4, 0) +#define KVMTRACE_3D(evt, vcpu, d1, d2, d3, name) \ + trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \ + vcpu, 3, d1, d2, d3, 0, 0) +#define KVMTRACE_2D(evt, vcpu, d1, d2, name) \ + trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \ + vcpu, 2, d1, d2, 0, 0, 0) +#define KVMTRACE_1D(evt, vcpu, d1, name) \ + trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \ + vcpu, 1, d1, 0, 0, 0, 0) +#define KVMTRACE_0D(evt, vcpu, name) \ + trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \ + vcpu, 0, 0, 0, 0, 0, 0) + #endif diff --git a/include/linux/kvm.h b/include/linux/kvm.h index f04bb426618f..d302d63517e4 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -14,6 +14,12 @@ #define KVM_API_VERSION 12 +/* for KVM_TRACE_ENABLE */ +struct kvm_user_trace_setup { + __u32 buf_size; /* sub_buffer size of each per-cpu */ + __u32 buf_nr; /* the number of sub_buffers of each per-cpu */ +}; + /* for KVM_CREATE_MEMORY_REGION */ struct kvm_memory_region { __u32 slot; @@ -242,6 +248,42 @@ struct kvm_s390_interrupt { __u64 parm64; }; +#define KVM_TRC_SHIFT 16 +/* + * kvm trace categories + */ +#define KVM_TRC_ENTRYEXIT (1 << KVM_TRC_SHIFT) +#define KVM_TRC_HANDLER (1 << (KVM_TRC_SHIFT + 1)) /* only 12 bits */ + +/* + * kvm trace action + */ +#define KVM_TRC_VMENTRY (KVM_TRC_ENTRYEXIT + 0x01) +#define KVM_TRC_VMEXIT (KVM_TRC_ENTRYEXIT + 0x02) +#define KVM_TRC_PAGE_FAULT (KVM_TRC_HANDLER + 0x01) + +#define KVM_TRC_HEAD_SIZE 12 +#define KVM_TRC_CYCLE_SIZE 8 +#define KVM_TRC_EXTRA_MAX 7 + +/* This structure represents a single trace buffer record. */ +struct kvm_trace_rec { + __u32 event:28; + __u32 extra_u32:3; + __u32 cycle_in:1; + __u32 pid; + __u32 vcpu_id; + union { + struct { + __u32 cycle_lo, cycle_hi; + __u32 extra_u32[KVM_TRC_EXTRA_MAX]; + } cycle; + struct { + __u32 extra_u32[KVM_TRC_EXTRA_MAX]; + } nocycle; + } u; +}; + #define KVMIO 0xAE /* @@ -262,7 +304,12 @@ struct kvm_s390_interrupt { */ #define KVM_GET_VCPU_MMAP_SIZE _IO(KVMIO, 0x04) /* in bytes */ #define KVM_GET_SUPPORTED_CPUID _IOWR(KVMIO, 0x05, struct kvm_cpuid2) - +/* + * ioctls for kvm trace + */ +#define KVM_TRACE_ENABLE _IOW(KVMIO, 0x06, struct kvm_user_trace_setup) +#define KVM_TRACE_PAUSE _IO(KVMIO, 0x07) +#define KVM_TRACE_DISABLE _IO(KVMIO, 0x08) /* * Extension capability list. */ -- cgit v1.2.3 From d4c9ff2d1b78e385471b3f4d80c0596909926ef7 Mon Sep 17 00:00:00 2001 From: "Feng(Eric) Liu" Date: Thu, 10 Apr 2008 08:47:53 -0400 Subject: KVM: Add kvm trace userspace interface This interface allows user a space application to read the trace of kvm related events through relayfs. Signed-off-by: Feng (Eric) Liu Signed-off-by: Avi Kivity --- include/linux/kvm_host.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include') diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 578c3638bbba..bd0c2d2d840f 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -309,5 +310,18 @@ struct kvm_stats_debugfs_item { struct dentry *dentry; }; extern struct kvm_stats_debugfs_item debugfs_entries[]; +extern struct dentry *debugfs_dir; + +#ifdef CONFIG_KVM_TRACE +int kvm_trace_ioctl(unsigned int ioctl, unsigned long arg); +void kvm_trace_cleanup(void); +#else +static inline +int kvm_trace_ioctl(unsigned int ioctl, unsigned long arg) +{ + return -EINVAL; +} +#define kvm_trace_cleanup() ((void)0) +#endif #endif -- cgit v1.2.3 From 3d80840d96127401ba6aeadd813c3a15b84e70fe Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Fri, 11 Apr 2008 14:53:26 -0300 Subject: KVM: hlt emulation should take in-kernel APIC/PIT timers into account Timers that fire between guest hlt and vcpu_block's add_wait_queue() are ignored, possibly resulting in hangs. Also make sure that atomic_inc and waitqueue_active tests happen in the specified order, otherwise the following race is open: CPU0 CPU1 if (waitqueue_active(wq)) add_wait_queue() if (!atomic_read(pit_timer->pending)) schedule() atomic_inc(pit_timer->pending) Signed-off-by: Marcelo Tosatti Signed-off-by: Avi Kivity --- include/linux/kvm_host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index bd0c2d2d840f..0bc400387cae 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -269,6 +269,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm); int kvm_cpu_get_interrupt(struct kvm_vcpu *v); int kvm_cpu_has_interrupt(struct kvm_vcpu *v); +int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu); void kvm_vcpu_kick(struct kvm_vcpu *vcpu); static inline void kvm_guest_enter(void) -- cgit v1.2.3 From a45352908b88d383bc40e1e4d1a6cc5bbcefc895 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 13 Apr 2008 17:54:35 +0300 Subject: KVM: Rename VCPU_MP_STATE_* to KVM_MP_STATE_* We wish to export it to userspace, so move it into the kvm namespace. Signed-off-by: Avi Kivity --- include/asm-ia64/kvm_host.h | 8 ++++---- include/asm-x86/kvm_host.h | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/include/asm-ia64/kvm_host.h b/include/asm-ia64/kvm_host.h index d6d6e15c1924..c082c208c1f3 100644 --- a/include/asm-ia64/kvm_host.h +++ b/include/asm-ia64/kvm_host.h @@ -318,10 +318,10 @@ struct kvm_vcpu_arch { int vmm_tr_slot; int vm_tr_slot; -#define VCPU_MP_STATE_RUNNABLE 0 -#define VCPU_MP_STATE_UNINITIALIZED 1 -#define VCPU_MP_STATE_INIT_RECEIVED 2 -#define VCPU_MP_STATE_HALTED 3 +#define KVM_MP_STATE_RUNNABLE 0 +#define KVM_MP_STATE_UNINITIALIZED 1 +#define KVM_MP_STATE_INIT_RECEIVED 2 +#define KVM_MP_STATE_HALTED 3 int mp_state; #define MAX_PTC_G_NUM 3 diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 15169cb71c83..f35a6ad43c0a 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -227,11 +227,11 @@ struct kvm_vcpu_arch { u64 shadow_efer; u64 apic_base; struct kvm_lapic *apic; /* kernel irqchip context */ -#define VCPU_MP_STATE_RUNNABLE 0 -#define VCPU_MP_STATE_UNINITIALIZED 1 -#define VCPU_MP_STATE_INIT_RECEIVED 2 -#define VCPU_MP_STATE_SIPI_RECEIVED 3 -#define VCPU_MP_STATE_HALTED 4 +#define KVM_MP_STATE_RUNNABLE 0 +#define KVM_MP_STATE_UNINITIALIZED 1 +#define KVM_MP_STATE_INIT_RECEIVED 2 +#define KVM_MP_STATE_SIPI_RECEIVED 3 +#define KVM_MP_STATE_HALTED 4 int mp_state; int sipi_vector; u64 ia32_misc_enable_msr; -- cgit v1.2.3 From 62d9f0dbc92d7e398fde53fc6021338393522e68 Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Fri, 11 Apr 2008 13:24:45 -0300 Subject: KVM: add ioctls to save/store mpstate So userspace can save/restore the mpstate during migration. [avi: export the #define constants describing the value] [christian: add s390 stubs] [avi: ditto for ia64] Signed-off-by: Marcelo Tosatti Signed-off-by: Christian Borntraeger Signed-off-by: Carsten Otte Signed-off-by: Avi Kivity --- include/asm-x86/kvm_host.h | 5 ----- include/linux/kvm.h | 15 +++++++++++++++ include/linux/kvm_host.h | 4 ++++ 3 files changed, 19 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index f35a6ad43c0a..9d963cd6533c 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -227,11 +227,6 @@ struct kvm_vcpu_arch { u64 shadow_efer; u64 apic_base; struct kvm_lapic *apic; /* kernel irqchip context */ -#define KVM_MP_STATE_RUNNABLE 0 -#define KVM_MP_STATE_UNINITIALIZED 1 -#define KVM_MP_STATE_INIT_RECEIVED 2 -#define KVM_MP_STATE_SIPI_RECEIVED 3 -#define KVM_MP_STATE_HALTED 4 int mp_state; int sipi_vector; u64 ia32_misc_enable_msr; diff --git a/include/linux/kvm.h b/include/linux/kvm.h index d302d63517e4..f8e211d8ce88 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -228,6 +228,18 @@ struct kvm_vapic_addr { __u64 vapic_addr; }; +/* for KVM_SET_MPSTATE */ + +#define KVM_MP_STATE_RUNNABLE 0 +#define KVM_MP_STATE_UNINITIALIZED 1 +#define KVM_MP_STATE_INIT_RECEIVED 2 +#define KVM_MP_STATE_HALTED 3 +#define KVM_MP_STATE_SIPI_RECEIVED 4 + +struct kvm_mp_state { + __u32 mp_state; +}; + struct kvm_s390_psw { __u64 mask; __u64 addr; @@ -326,6 +338,7 @@ struct kvm_trace_rec { #define KVM_CAP_PIT 11 #define KVM_CAP_NOP_IO_DELAY 12 #define KVM_CAP_PV_MMU 13 +#define KVM_CAP_MP_STATE 14 /* * ioctls for VM fds @@ -387,5 +400,7 @@ struct kvm_trace_rec { #define KVM_S390_SET_INITIAL_PSW _IOW(KVMIO, 0x96, struct kvm_s390_psw) /* initial reset for s390 */ #define KVM_S390_INITIAL_RESET _IO(KVMIO, 0x97) +#define KVM_GET_MP_STATE _IOR(KVMIO, 0x98, struct kvm_mp_state) +#define KVM_SET_MP_STATE _IOW(KVMIO, 0x99, struct kvm_mp_state) #endif diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 0bc400387cae..81d4c3305a28 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -237,6 +237,10 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); +int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, + struct kvm_mp_state *mp_state); +int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, + struct kvm_mp_state *mp_state); int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg); int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run); -- cgit v1.2.3 From 76f7c87902fd2c2de9eb57168adbf9bc5ec2047d Mon Sep 17 00:00:00 2001 From: Hollis Blanchard Date: Tue, 15 Apr 2008 16:05:42 -0500 Subject: KVM: Rename debugfs_dir to kvm_debugfs_dir It's a globally exported symbol now. Signed-off-by: Hollis Blanchard Signed-off-by: Avi Kivity --- include/linux/kvm_host.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 81d4c3305a28..4e16682ee8bb 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -315,7 +315,7 @@ struct kvm_stats_debugfs_item { struct dentry *dentry; }; extern struct kvm_stats_debugfs_item debugfs_entries[]; -extern struct dentry *debugfs_dir; +extern struct dentry *kvm_debugfs_dir; #ifdef CONFIG_KVM_TRACE int kvm_trace_ioctl(unsigned int ioctl, unsigned long arg); -- cgit v1.2.3 From 4baacfb0de53b05428c87d377fc8a3def4dc10e7 Mon Sep 17 00:00:00 2001 From: Hollis Blanchard Date: Wed, 16 Apr 2008 23:28:06 -0500 Subject: ppc: Export tlb_44x_hwater for KVM PowerPC 440 KVM needs to know how many TLB entries are used for the host kernel linear mapping (it does not modify these mappings when switching between guest and host execution). Signed-off-by: Hollis Blanchard Acked-by: Josh Boyer Acked-by: Paul Mackerras Signed-off-by: Avi Kivity --- include/asm-powerpc/mmu-44x.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/asm-powerpc/mmu-44x.h b/include/asm-powerpc/mmu-44x.h index c8b02d97f753..a825524c981a 100644 --- a/include/asm-powerpc/mmu-44x.h +++ b/include/asm-powerpc/mmu-44x.h @@ -53,6 +53,8 @@ #ifndef __ASSEMBLY__ +extern unsigned int tlb_44x_hwater; + typedef struct { unsigned long id; unsigned long vdso_base; -- cgit v1.2.3 From b2312f059c893833de58876c74290511846cd208 Mon Sep 17 00:00:00 2001 From: Hollis Blanchard Date: Wed, 16 Apr 2008 23:28:07 -0500 Subject: KVM: ppc: Add DCR access information to struct kvm_run Device Control Registers are essentially another address space found on PowerPC 4xx processors, analogous to PIO on x86. DCRs are always 32 bits, and can be identified by a 32-bit number. We forward most DCR accesses to userspace for emulation (with the exception of CPR0 registers, which can be read directly for simplicity in timebase frequency determination). Signed-off-by: Hollis Blanchard Signed-off-by: Avi Kivity --- include/linux/kvm.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include') diff --git a/include/linux/kvm.h b/include/linux/kvm.h index f8e211d8ce88..a281afeddfbb 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -82,6 +82,7 @@ struct kvm_irqchip { #define KVM_EXIT_TPR_ACCESS 12 #define KVM_EXIT_S390_SIEIC 13 #define KVM_EXIT_S390_RESET 14 +#define KVM_EXIT_DCR 15 /* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */ struct kvm_run { @@ -161,6 +162,12 @@ struct kvm_run { #define KVM_S390_RESET_CPU_INIT 8 #define KVM_S390_RESET_IPL 16 __u64 s390_reset_flags; + /* KVM_EXIT_DCR */ + struct { + __u32 dcrn; + __u32 data; + __u8 is_write; + } dcr; /* Fix the size of the union. */ char padding[256]; }; -- cgit v1.2.3 From bbf45ba57eaec56569918a8bab96ab653bd45ec1 Mon Sep 17 00:00:00 2001 From: Hollis Blanchard Date: Wed, 16 Apr 2008 23:28:09 -0500 Subject: KVM: ppc: PowerPC 440 KVM implementation This functionality is definitely experimental, but is capable of running unmodified PowerPC 440 Linux kernels as guests on a PowerPC 440 host. (Only tested with 440EP "Bamboo" guests so far, but with appropriate userspace support other SoC/board combinations should work.) See Documentation/powerpc/kvm_440.txt for technical details. [stephen: build fix] Signed-off-by: Hollis Blanchard Acked-by: Paul Mackerras Signed-off-by: Stephen Rothwell Signed-off-by: Avi Kivity --- include/asm-powerpc/kvm.h | 53 +++++++++++++- include/asm-powerpc/kvm_asm.h | 55 +++++++++++++++ include/asm-powerpc/kvm_host.h | 152 +++++++++++++++++++++++++++++++++++++++++ include/asm-powerpc/kvm_para.h | 37 ++++++++++ include/asm-powerpc/kvm_ppc.h | 88 ++++++++++++++++++++++++ 5 files changed, 383 insertions(+), 2 deletions(-) create mode 100644 include/asm-powerpc/kvm_asm.h create mode 100644 include/asm-powerpc/kvm_host.h create mode 100644 include/asm-powerpc/kvm_para.h create mode 100644 include/asm-powerpc/kvm_ppc.h (limited to 'include') diff --git a/include/asm-powerpc/kvm.h b/include/asm-powerpc/kvm.h index d1b530fbf8dd..f993e4198d5c 100644 --- a/include/asm-powerpc/kvm.h +++ b/include/asm-powerpc/kvm.h @@ -1,6 +1,55 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright IBM Corp. 2007 + * + * Authors: Hollis Blanchard + */ + #ifndef __LINUX_KVM_POWERPC_H #define __LINUX_KVM_POWERPC_H -/* powerpc does not support KVM */ +#include + +struct kvm_regs { + __u64 pc; + __u64 cr; + __u64 ctr; + __u64 lr; + __u64 xer; + __u64 msr; + __u64 srr0; + __u64 srr1; + __u64 pid; + + __u64 sprg0; + __u64 sprg1; + __u64 sprg2; + __u64 sprg3; + __u64 sprg4; + __u64 sprg5; + __u64 sprg6; + __u64 sprg7; + + __u64 gpr[32]; +}; + +struct kvm_sregs { +}; + +struct kvm_fpu { + __u64 fpr[32]; +}; -#endif +#endif /* __LINUX_KVM_POWERPC_H */ diff --git a/include/asm-powerpc/kvm_asm.h b/include/asm-powerpc/kvm_asm.h new file mode 100644 index 000000000000..2197764796d9 --- /dev/null +++ b/include/asm-powerpc/kvm_asm.h @@ -0,0 +1,55 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright IBM Corp. 2008 + * + * Authors: Hollis Blanchard + */ + +#ifndef __POWERPC_KVM_ASM_H__ +#define __POWERPC_KVM_ASM_H__ + +/* IVPR must be 64KiB-aligned. */ +#define VCPU_SIZE_ORDER 4 +#define VCPU_SIZE_LOG (VCPU_SIZE_ORDER + 12) +#define VCPU_TLB_PGSZ PPC44x_TLB_64K +#define VCPU_SIZE_BYTES (1< + */ + +#ifndef __POWERPC_KVM_HOST_H__ +#define __POWERPC_KVM_HOST_H__ + +#include +#include +#include +#include +#include + +#define KVM_MAX_VCPUS 1 +#define KVM_MEMORY_SLOTS 32 +/* memory slots that does not exposed to userspace */ +#define KVM_PRIVATE_MEM_SLOTS 4 + +/* We don't currently support large pages. */ +#define KVM_PAGES_PER_HPAGE (1<<31) + +struct kvm; +struct kvm_run; +struct kvm_vcpu; + +struct kvm_vm_stat { + u32 remote_tlb_flush; +}; + +struct kvm_vcpu_stat { + u32 sum_exits; + u32 mmio_exits; + u32 dcr_exits; + u32 signal_exits; + u32 light_exits; + /* Account for special types of light exits: */ + u32 itlb_real_miss_exits; + u32 itlb_virt_miss_exits; + u32 dtlb_real_miss_exits; + u32 dtlb_virt_miss_exits; + u32 syscall_exits; + u32 isi_exits; + u32 dsi_exits; + u32 emulated_inst_exits; + u32 dec_exits; + u32 ext_intr_exits; +}; + +struct tlbe { + u32 tid; /* Only the low 8 bits are used. */ + u32 word0; + u32 word1; + u32 word2; +}; + +struct kvm_arch { +}; + +struct kvm_vcpu_arch { + /* Unmodified copy of the guest's TLB. */ + struct tlbe guest_tlb[PPC44x_TLB_SIZE]; + /* TLB that's actually used when the guest is running. */ + struct tlbe shadow_tlb[PPC44x_TLB_SIZE]; + /* Pages which are referenced in the shadow TLB. */ + struct page *shadow_pages[PPC44x_TLB_SIZE]; + /* Copy of the host's TLB. */ + struct tlbe host_tlb[PPC44x_TLB_SIZE]; + + u32 host_stack; + u32 host_pid; + + u64 fpr[32]; + u32 gpr[32]; + + u32 pc; + u32 cr; + u32 ctr; + u32 lr; + u32 xer; + + u32 msr; + u32 mmucr; + u32 sprg0; + u32 sprg1; + u32 sprg2; + u32 sprg3; + u32 sprg4; + u32 sprg5; + u32 sprg6; + u32 sprg7; + u32 srr0; + u32 srr1; + u32 csrr0; + u32 csrr1; + u32 dsrr0; + u32 dsrr1; + u32 dear; + u32 esr; + u32 dec; + u32 decar; + u32 tbl; + u32 tbu; + u32 tcr; + u32 tsr; + u32 ivor[16]; + u32 ivpr; + u32 pir; + u32 pid; + u32 pvr; + u32 ccr0; + u32 ccr1; + u32 dbcr0; + u32 dbcr1; + + u32 last_inst; + u32 fault_dear; + u32 fault_esr; + gpa_t paddr_accessed; + + u8 io_gpr; /* GPR used as IO source/target */ + u8 mmio_is_bigendian; + u8 dcr_needed; + u8 dcr_is_write; + + u32 cpr0_cfgaddr; /* holds the last set cpr0_cfgaddr */ + + struct timer_list dec_timer; + unsigned long pending_exceptions; +}; + +struct kvm_guest_debug { + int enabled; + unsigned long bp[4]; + int singlestep; +}; + +#endif /* __POWERPC_KVM_HOST_H__ */ diff --git a/include/asm-powerpc/kvm_para.h b/include/asm-powerpc/kvm_para.h new file mode 100644 index 000000000000..2d48f6a63d0b --- /dev/null +++ b/include/asm-powerpc/kvm_para.h @@ -0,0 +1,37 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright IBM Corp. 2008 + * + * Authors: Hollis Blanchard + */ + +#ifndef __POWERPC_KVM_PARA_H__ +#define __POWERPC_KVM_PARA_H__ + +#ifdef __KERNEL__ + +static inline int kvm_para_available(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_para_features(void) +{ + return 0; +} + +#endif /* __KERNEL__ */ + +#endif /* __POWERPC_KVM_PARA_H__ */ diff --git a/include/asm-powerpc/kvm_ppc.h b/include/asm-powerpc/kvm_ppc.h new file mode 100644 index 000000000000..7ac820308a7e --- /dev/null +++ b/include/asm-powerpc/kvm_ppc.h @@ -0,0 +1,88 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright IBM Corp. 2008 + * + * Authors: Hollis Blanchard + */ + +#ifndef __POWERPC_KVM_PPC_H__ +#define __POWERPC_KVM_PPC_H__ + +/* This file exists just so we can dereference kvm_vcpu, avoiding nested header + * dependencies. */ + +#include +#include +#include +#include +#include + +struct kvm_tlb { + struct tlbe guest_tlb[PPC44x_TLB_SIZE]; + struct tlbe shadow_tlb[PPC44x_TLB_SIZE]; +}; + +enum emulation_result { + EMULATE_DONE, /* no further processing */ + EMULATE_DO_MMIO, /* kvm_run filled with MMIO request */ + EMULATE_DO_DCR, /* kvm_run filled with DCR request */ + EMULATE_FAIL, /* can't emulate this instruction */ +}; + +extern const unsigned char exception_priority[]; +extern const unsigned char priority_exception[]; + +extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); +extern char kvmppc_handlers_start[]; +extern unsigned long kvmppc_handler_len; + +extern void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu); +extern int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, + unsigned int rt, unsigned int bytes, + int is_bigendian); +extern int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, + u32 val, unsigned int bytes, int is_bigendian); + +extern int kvmppc_emulate_instruction(struct kvm_run *run, + struct kvm_vcpu *vcpu); + +extern void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, + u64 asid, u32 flags); +extern void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, u64 eaddr, u64 asid); +extern void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode); + +extern void kvmppc_check_and_deliver_interrupts(struct kvm_vcpu *vcpu); + +static inline void kvmppc_queue_exception(struct kvm_vcpu *vcpu, int exception) +{ + unsigned int priority = exception_priority[exception]; + set_bit(priority, &vcpu->arch.pending_exceptions); +} + +static inline void kvmppc_clear_exception(struct kvm_vcpu *vcpu, int exception) +{ + unsigned int priority = exception_priority[exception]; + clear_bit(priority, &vcpu->arch.pending_exceptions); +} + +static inline void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr) +{ + if ((new_msr & MSR_PR) != (vcpu->arch.msr & MSR_PR)) + kvmppc_mmu_priv_switch(vcpu, new_msr & MSR_PR); + + vcpu->arch.msr = new_msr; +} + +#endif /* __POWERPC_KVM_PPC_H__ */ -- cgit v1.2.3 From 66c0b394f08fd89236515c1c84485ea712a157be Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 19 Apr 2008 20:33:56 +0100 Subject: KVM: kill file->f_count abuse in kvm Use kvm own refcounting instead of playing with ->filp->f_count. That will allow to get rid of a lot of crap in anon_inode_getfd() and kill a race in kvm_dev_ioctl_create_vm() (file might have been closed immediately by another thread, so ->filp might point to already freed struct file when we get around to setting it). Signed-off-by: Al Viro Signed-off-by: Avi Kivity --- include/linux/kvm_host.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 4e16682ee8bb..398978972b7a 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -110,7 +110,6 @@ struct kvm { KVM_PRIVATE_MEM_SLOTS]; struct kvm_vcpu *vcpus[KVM_MAX_VCPUS]; struct list_head vm_list; - struct file *filp; struct kvm_io_bus mmio_bus; struct kvm_io_bus pio_bus; struct kvm_vm_stat stat; -- cgit v1.2.3