diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2014-02-03 22:23:37 -0500 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-02-03 22:23:37 -0500 |
commit | f244d910ea2974d88efcc6d04594f25e22718f90 (patch) | |
tree | 7236a244a09fa76d73105df476d2f20a19066d70 /arch/s390/include | |
parent | 4f34d683e52271197e1ee17b7095e8ba27761ba6 (diff) | |
parent | 536336c21697551ceca44bdffb9f53e6cc5f2f20 (diff) |
Merge tag 'kvm-s390-20140130' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into HEAD
Two new features are added by this patch set:
- The floating interrupt controller (flic) that allows us to inject,
clear and inspect non-vcpu local interrupts. This also gives us an
opportunity to fix deficiencies in our existing interrupt definitions.
- Support for asynchronous page faults via the pfault mechanism. Testing
show significant guest performance improvements under host swap.
Diffstat (limited to 'arch/s390/include')
-rw-r--r-- | arch/s390/include/asm/kvm_host.h | 58 | ||||
-rw-r--r-- | arch/s390/include/asm/pgtable.h | 2 | ||||
-rw-r--r-- | arch/s390/include/asm/processor.h | 1 | ||||
-rw-r--r-- | arch/s390/include/uapi/asm/kvm.h | 19 |
4 files changed, 47 insertions, 33 deletions
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index eef3dd3fd9a9..2c69ba285e81 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/hrtimer.h> | 16 | #include <linux/hrtimer.h> |
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/kvm_host.h> | 18 | #include <linux/kvm_host.h> |
19 | #include <linux/kvm.h> | ||
19 | #include <asm/debug.h> | 20 | #include <asm/debug.h> |
20 | #include <asm/cpu.h> | 21 | #include <asm/cpu.h> |
21 | 22 | ||
@@ -168,18 +169,6 @@ struct kvm_vcpu_stat { | |||
168 | u32 diagnose_9c; | 169 | u32 diagnose_9c; |
169 | }; | 170 | }; |
170 | 171 | ||
171 | struct kvm_s390_io_info { | ||
172 | __u16 subchannel_id; /* 0x0b8 */ | ||
173 | __u16 subchannel_nr; /* 0x0ba */ | ||
174 | __u32 io_int_parm; /* 0x0bc */ | ||
175 | __u32 io_int_word; /* 0x0c0 */ | ||
176 | }; | ||
177 | |||
178 | struct kvm_s390_ext_info { | ||
179 | __u32 ext_params; | ||
180 | __u64 ext_params2; | ||
181 | }; | ||
182 | |||
183 | #define PGM_OPERATION 0x01 | 172 | #define PGM_OPERATION 0x01 |
184 | #define PGM_PRIVILEGED_OP 0x02 | 173 | #define PGM_PRIVILEGED_OP 0x02 |
185 | #define PGM_EXECUTE 0x03 | 174 | #define PGM_EXECUTE 0x03 |
@@ -188,27 +177,6 @@ struct kvm_s390_ext_info { | |||
188 | #define PGM_SPECIFICATION 0x06 | 177 | #define PGM_SPECIFICATION 0x06 |
189 | #define PGM_DATA 0x07 | 178 | #define PGM_DATA 0x07 |
190 | 179 | ||
191 | struct kvm_s390_pgm_info { | ||
192 | __u16 code; | ||
193 | }; | ||
194 | |||
195 | struct kvm_s390_prefix_info { | ||
196 | __u32 address; | ||
197 | }; | ||
198 | |||
199 | struct kvm_s390_extcall_info { | ||
200 | __u16 code; | ||
201 | }; | ||
202 | |||
203 | struct kvm_s390_emerg_info { | ||
204 | __u16 code; | ||
205 | }; | ||
206 | |||
207 | struct kvm_s390_mchk_info { | ||
208 | __u64 cr14; | ||
209 | __u64 mcic; | ||
210 | }; | ||
211 | |||
212 | struct kvm_s390_interrupt_info { | 180 | struct kvm_s390_interrupt_info { |
213 | struct list_head list; | 181 | struct list_head list; |
214 | u64 type; | 182 | u64 type; |
@@ -246,6 +214,7 @@ struct kvm_s390_float_interrupt { | |||
246 | unsigned long idle_mask[(KVM_MAX_VCPUS + sizeof(long) - 1) | 214 | unsigned long idle_mask[(KVM_MAX_VCPUS + sizeof(long) - 1) |
247 | / sizeof(long)]; | 215 | / sizeof(long)]; |
248 | struct kvm_s390_local_interrupt *local_int[KVM_MAX_VCPUS]; | 216 | struct kvm_s390_local_interrupt *local_int[KVM_MAX_VCPUS]; |
217 | unsigned int irq_count; | ||
249 | }; | 218 | }; |
250 | 219 | ||
251 | 220 | ||
@@ -262,6 +231,10 @@ struct kvm_vcpu_arch { | |||
262 | u64 stidp_data; | 231 | u64 stidp_data; |
263 | }; | 232 | }; |
264 | struct gmap *gmap; | 233 | struct gmap *gmap; |
234 | #define KVM_S390_PFAULT_TOKEN_INVALID (-1UL) | ||
235 | unsigned long pfault_token; | ||
236 | unsigned long pfault_select; | ||
237 | unsigned long pfault_compare; | ||
265 | }; | 238 | }; |
266 | 239 | ||
267 | struct kvm_vm_stat { | 240 | struct kvm_vm_stat { |
@@ -275,6 +248,7 @@ struct kvm_arch{ | |||
275 | struct sca_block *sca; | 248 | struct sca_block *sca; |
276 | debug_info_t *dbf; | 249 | debug_info_t *dbf; |
277 | struct kvm_s390_float_interrupt float_int; | 250 | struct kvm_s390_float_interrupt float_int; |
251 | struct kvm_device *flic; | ||
278 | struct gmap *gmap; | 252 | struct gmap *gmap; |
279 | int css_support; | 253 | int css_support; |
280 | }; | 254 | }; |
@@ -287,6 +261,24 @@ static inline bool kvm_is_error_hva(unsigned long addr) | |||
287 | return IS_ERR_VALUE(addr); | 261 | return IS_ERR_VALUE(addr); |
288 | } | 262 | } |
289 | 263 | ||
264 | #define ASYNC_PF_PER_VCPU 64 | ||
265 | struct kvm_vcpu; | ||
266 | struct kvm_async_pf; | ||
267 | struct kvm_arch_async_pf { | ||
268 | unsigned long pfault_token; | ||
269 | }; | ||
270 | |||
271 | bool kvm_arch_can_inject_async_page_present(struct kvm_vcpu *vcpu); | ||
272 | |||
273 | void kvm_arch_async_page_ready(struct kvm_vcpu *vcpu, | ||
274 | struct kvm_async_pf *work); | ||
275 | |||
276 | void kvm_arch_async_page_not_present(struct kvm_vcpu *vcpu, | ||
277 | struct kvm_async_pf *work); | ||
278 | |||
279 | void kvm_arch_async_page_present(struct kvm_vcpu *vcpu, | ||
280 | struct kvm_async_pf *work); | ||
281 | |||
290 | extern int sie64a(struct kvm_s390_sie_block *, u64 *); | 282 | extern int sie64a(struct kvm_s390_sie_block *, u64 *); |
291 | extern char sie_exit; | 283 | extern char sie_exit; |
292 | #endif | 284 | #endif |
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 2204400d0bd5..66101f6c6d81 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
@@ -767,6 +767,7 @@ static inline void pgste_set_pte(pte_t *ptep, pte_t entry) | |||
767 | * @table: pointer to the page directory | 767 | * @table: pointer to the page directory |
768 | * @asce: address space control element for gmap page table | 768 | * @asce: address space control element for gmap page table |
769 | * @crst_list: list of all crst tables used in the guest address space | 769 | * @crst_list: list of all crst tables used in the guest address space |
770 | * @pfault_enabled: defines if pfaults are applicable for the guest | ||
770 | */ | 771 | */ |
771 | struct gmap { | 772 | struct gmap { |
772 | struct list_head list; | 773 | struct list_head list; |
@@ -775,6 +776,7 @@ struct gmap { | |||
775 | unsigned long asce; | 776 | unsigned long asce; |
776 | void *private; | 777 | void *private; |
777 | struct list_head crst_list; | 778 | struct list_head crst_list; |
779 | bool pfault_enabled; | ||
778 | }; | 780 | }; |
779 | 781 | ||
780 | /** | 782 | /** |
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index 0a876bc543d3..dc5fc4f90e52 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h | |||
@@ -79,6 +79,7 @@ struct thread_struct { | |||
79 | unsigned long ksp; /* kernel stack pointer */ | 79 | unsigned long ksp; /* kernel stack pointer */ |
80 | mm_segment_t mm_segment; | 80 | mm_segment_t mm_segment; |
81 | unsigned long gmap_addr; /* address of last gmap fault. */ | 81 | unsigned long gmap_addr; /* address of last gmap fault. */ |
82 | unsigned int gmap_pfault; /* signal of a pending guest pfault */ | ||
82 | struct per_regs per_user; /* User specified PER registers */ | 83 | struct per_regs per_user; /* User specified PER registers */ |
83 | struct per_event per_event; /* Cause of the last PER trap */ | 84 | struct per_event per_event; /* Cause of the last PER trap */ |
84 | unsigned long per_flags; /* Flags to control debug behavior */ | 85 | unsigned long per_flags; /* Flags to control debug behavior */ |
diff --git a/arch/s390/include/uapi/asm/kvm.h b/arch/s390/include/uapi/asm/kvm.h index d25da598ec62..cb4c1eb8a0a5 100644 --- a/arch/s390/include/uapi/asm/kvm.h +++ b/arch/s390/include/uapi/asm/kvm.h | |||
@@ -16,6 +16,22 @@ | |||
16 | 16 | ||
17 | #define __KVM_S390 | 17 | #define __KVM_S390 |
18 | 18 | ||
19 | /* Device control API: s390-specific devices */ | ||
20 | #define KVM_DEV_FLIC_GET_ALL_IRQS 1 | ||
21 | #define KVM_DEV_FLIC_ENQUEUE 2 | ||
22 | #define KVM_DEV_FLIC_CLEAR_IRQS 3 | ||
23 | #define KVM_DEV_FLIC_APF_ENABLE 4 | ||
24 | #define KVM_DEV_FLIC_APF_DISABLE_WAIT 5 | ||
25 | /* | ||
26 | * We can have up to 4*64k pending subchannels + 8 adapter interrupts, | ||
27 | * as well as up to ASYNC_PF_PER_VCPU*KVM_MAX_VCPUS pfault done interrupts. | ||
28 | * There are also sclp and machine checks. This gives us | ||
29 | * sizeof(kvm_s390_irq)*(4*65536+8+64*64+1+1) = 72 * 266250 = 19170000 | ||
30 | * Lets round up to 8192 pages. | ||
31 | */ | ||
32 | #define KVM_S390_MAX_FLOAT_IRQS 266250 | ||
33 | #define KVM_S390_FLIC_MAX_BUFFER 0x2000000 | ||
34 | |||
19 | /* for KVM_GET_REGS and KVM_SET_REGS */ | 35 | /* for KVM_GET_REGS and KVM_SET_REGS */ |
20 | struct kvm_regs { | 36 | struct kvm_regs { |
21 | /* general purpose regs for s390 */ | 37 | /* general purpose regs for s390 */ |
@@ -57,4 +73,7 @@ struct kvm_sync_regs { | |||
57 | #define KVM_REG_S390_EPOCHDIFF (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x2) | 73 | #define KVM_REG_S390_EPOCHDIFF (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x2) |
58 | #define KVM_REG_S390_CPU_TIMER (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x3) | 74 | #define KVM_REG_S390_CPU_TIMER (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x3) |
59 | #define KVM_REG_S390_CLOCK_COMP (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x4) | 75 | #define KVM_REG_S390_CLOCK_COMP (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x4) |
76 | #define KVM_REG_S390_PFTOKEN (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x5) | ||
77 | #define KVM_REG_S390_PFCOMPARE (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x6) | ||
78 | #define KVM_REG_S390_PFSELECT (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x7) | ||
60 | #endif | 79 | #endif |