diff options
| -rw-r--r-- | Documentation/virtual/kvm/api.txt | 27 | ||||
| -rw-r--r-- | Documentation/virtual/kvm/devices/s390_flic.txt | 45 | ||||
| -rw-r--r-- | arch/mips/include/asm/kvm_host.h | 417 | ||||
| -rw-r--r-- | arch/mips/kvm/kvm_mips_emul.c | 40 | ||||
| -rw-r--r-- | arch/s390/include/asm/kvm_host.h | 32 | ||||
| -rw-r--r-- | arch/s390/include/uapi/asm/kvm.h | 22 | ||||
| -rw-r--r-- | arch/s390/kvm/Kconfig | 2 | ||||
| -rw-r--r-- | arch/s390/kvm/Makefile | 2 | ||||
| -rw-r--r-- | arch/s390/kvm/interrupt.c | 294 | ||||
| -rw-r--r-- | arch/s390/kvm/irq.h | 22 | ||||
| -rw-r--r-- | arch/s390/kvm/kvm-s390.c | 42 | ||||
| -rw-r--r-- | arch/s390/kvm/kvm-s390.h | 2 | ||||
| -rw-r--r-- | arch/x86/kvm/cpuid.c | 30 | ||||
| -rw-r--r-- | arch/x86/kvm/svm.c | 6 | ||||
| -rw-r--r-- | arch/x86/kvm/vmx.c | 22 | ||||
| -rw-r--r-- | arch/x86/kvm/x86.c | 21 | ||||
| -rw-r--r-- | arch/x86/kvm/x86.h | 2 | ||||
| -rw-r--r-- | include/linux/kvm_host.h | 13 | ||||
| -rw-r--r-- | include/uapi/linux/kvm.h | 16 | ||||
| -rw-r--r-- | virt/kvm/eventfd.c | 8 | ||||
| -rw-r--r-- | virt/kvm/ioapic.c | 107 |
21 files changed, 878 insertions, 294 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 4714f282a43e..2cb1640a90ad 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt | |||
| @@ -586,8 +586,8 @@ struct kvm_fpu { | |||
| 586 | 586 | ||
| 587 | 4.24 KVM_CREATE_IRQCHIP | 587 | 4.24 KVM_CREATE_IRQCHIP |
| 588 | 588 | ||
| 589 | Capability: KVM_CAP_IRQCHIP | 589 | Capability: KVM_CAP_IRQCHIP, KVM_CAP_S390_IRQCHIP (s390) |
| 590 | Architectures: x86, ia64, ARM, arm64 | 590 | Architectures: x86, ia64, ARM, arm64, s390 |
| 591 | Type: vm ioctl | 591 | Type: vm ioctl |
| 592 | Parameters: none | 592 | Parameters: none |
| 593 | Returns: 0 on success, -1 on error | 593 | Returns: 0 on success, -1 on error |
| @@ -596,7 +596,10 @@ Creates an interrupt controller model in the kernel. On x86, creates a virtual | |||
| 596 | ioapic, a virtual PIC (two PICs, nested), and sets up future vcpus to have a | 596 | ioapic, a virtual PIC (two PICs, nested), and sets up future vcpus to have a |
| 597 | local APIC. IRQ routing for GSIs 0-15 is set to both PIC and IOAPIC; GSI 16-23 | 597 | local APIC. IRQ routing for GSIs 0-15 is set to both PIC and IOAPIC; GSI 16-23 |
| 598 | only go to the IOAPIC. On ia64, a IOSAPIC is created. On ARM/arm64, a GIC is | 598 | only go to the IOAPIC. On ia64, a IOSAPIC is created. On ARM/arm64, a GIC is |
| 599 | created. | 599 | created. On s390, a dummy irq routing table is created. |
| 600 | |||
| 601 | Note that on s390 the KVM_CAP_S390_IRQCHIP vm capability needs to be enabled | ||
| 602 | before KVM_CREATE_IRQCHIP can be used. | ||
| 600 | 603 | ||
| 601 | 604 | ||
| 602 | 4.25 KVM_IRQ_LINE | 605 | 4.25 KVM_IRQ_LINE |
| @@ -932,9 +935,9 @@ documentation when it pops into existence). | |||
| 932 | 935 | ||
| 933 | 4.37 KVM_ENABLE_CAP | 936 | 4.37 KVM_ENABLE_CAP |
| 934 | 937 | ||
| 935 | Capability: KVM_CAP_ENABLE_CAP | 938 | Capability: KVM_CAP_ENABLE_CAP, KVM_CAP_ENABLE_CAP_VM |
| 936 | Architectures: ppc, s390 | 939 | Architectures: ppc, s390 |
| 937 | Type: vcpu ioctl | 940 | Type: vcpu ioctl, vm ioctl (with KVM_CAP_ENABLE_CAP_VM) |
| 938 | Parameters: struct kvm_enable_cap (in) | 941 | Parameters: struct kvm_enable_cap (in) |
| 939 | Returns: 0 on success; -1 on error | 942 | Returns: 0 on success; -1 on error |
| 940 | 943 | ||
| @@ -965,6 +968,8 @@ function properly, this is the place to put them. | |||
| 965 | __u8 pad[64]; | 968 | __u8 pad[64]; |
| 966 | }; | 969 | }; |
| 967 | 970 | ||
| 971 | The vcpu ioctl should be used for vcpu-specific capabilities, the vm ioctl | ||
| 972 | for vm-wide capabilities. | ||
| 968 | 973 | ||
| 969 | 4.38 KVM_GET_MP_STATE | 974 | 4.38 KVM_GET_MP_STATE |
| 970 | 975 | ||
| @@ -1334,7 +1339,7 @@ KVM_ASSIGN_DEV_IRQ. Partial deassignment of host or guest IRQ is allowed. | |||
| 1334 | 4.52 KVM_SET_GSI_ROUTING | 1339 | 4.52 KVM_SET_GSI_ROUTING |
| 1335 | 1340 | ||
| 1336 | Capability: KVM_CAP_IRQ_ROUTING | 1341 | Capability: KVM_CAP_IRQ_ROUTING |
| 1337 | Architectures: x86 ia64 | 1342 | Architectures: x86 ia64 s390 |
| 1338 | Type: vm ioctl | 1343 | Type: vm ioctl |
| 1339 | Parameters: struct kvm_irq_routing (in) | 1344 | Parameters: struct kvm_irq_routing (in) |
| 1340 | Returns: 0 on success, -1 on error | 1345 | Returns: 0 on success, -1 on error |
| @@ -1357,6 +1362,7 @@ struct kvm_irq_routing_entry { | |||
| 1357 | union { | 1362 | union { |
| 1358 | struct kvm_irq_routing_irqchip irqchip; | 1363 | struct kvm_irq_routing_irqchip irqchip; |
| 1359 | struct kvm_irq_routing_msi msi; | 1364 | struct kvm_irq_routing_msi msi; |
| 1365 | struct kvm_irq_routing_s390_adapter adapter; | ||
| 1360 | __u32 pad[8]; | 1366 | __u32 pad[8]; |
| 1361 | } u; | 1367 | } u; |
| 1362 | }; | 1368 | }; |
| @@ -1364,6 +1370,7 @@ struct kvm_irq_routing_entry { | |||
| 1364 | /* gsi routing entry types */ | 1370 | /* gsi routing entry types */ |
| 1365 | #define KVM_IRQ_ROUTING_IRQCHIP 1 | 1371 | #define KVM_IRQ_ROUTING_IRQCHIP 1 |
| 1366 | #define KVM_IRQ_ROUTING_MSI 2 | 1372 | #define KVM_IRQ_ROUTING_MSI 2 |
| 1373 | #define KVM_IRQ_ROUTING_S390_ADAPTER 3 | ||
| 1367 | 1374 | ||
| 1368 | No flags are specified so far, the corresponding field must be set to zero. | 1375 | No flags are specified so far, the corresponding field must be set to zero. |
| 1369 | 1376 | ||
| @@ -1379,6 +1386,14 @@ struct kvm_irq_routing_msi { | |||
| 1379 | __u32 pad; | 1386 | __u32 pad; |
| 1380 | }; | 1387 | }; |
| 1381 | 1388 | ||
| 1389 | struct kvm_irq_routing_s390_adapter { | ||
| 1390 | __u64 ind_addr; | ||
| 1391 | __u64 summary_addr; | ||
| 1392 | __u64 ind_offset; | ||
| 1393 | __u32 summary_offset; | ||
| 1394 | __u32 adapter_id; | ||
| 1395 | }; | ||
| 1396 | |||
| 1382 | 1397 | ||
| 1383 | 4.53 KVM_ASSIGN_SET_MSIX_NR | 1398 | 4.53 KVM_ASSIGN_SET_MSIX_NR |
| 1384 | 1399 | ||
diff --git a/Documentation/virtual/kvm/devices/s390_flic.txt b/Documentation/virtual/kvm/devices/s390_flic.txt index 410fa673e5b6..4ceef53164b0 100644 --- a/Documentation/virtual/kvm/devices/s390_flic.txt +++ b/Documentation/virtual/kvm/devices/s390_flic.txt | |||
| @@ -12,6 +12,7 @@ FLIC provides support to | |||
| 12 | - inspect currently pending interrupts (KVM_FLIC_GET_ALL_IRQS) | 12 | - inspect currently pending interrupts (KVM_FLIC_GET_ALL_IRQS) |
| 13 | - purge all pending floating interrupts (KVM_DEV_FLIC_CLEAR_IRQS) | 13 | - purge all pending floating interrupts (KVM_DEV_FLIC_CLEAR_IRQS) |
| 14 | - enable/disable for the guest transparent async page faults | 14 | - enable/disable for the guest transparent async page faults |
| 15 | - register and modify adapter interrupt sources (KVM_DEV_FLIC_ADAPTER_*) | ||
| 15 | 16 | ||
| 16 | Groups: | 17 | Groups: |
| 17 | KVM_DEV_FLIC_ENQUEUE | 18 | KVM_DEV_FLIC_ENQUEUE |
| @@ -44,3 +45,47 @@ Groups: | |||
| 44 | Disables async page faults for the guest and waits until already pending | 45 | Disables async page faults for the guest and waits until already pending |
| 45 | async page faults are done. This is necessary to trigger a completion interrupt | 46 | async page faults are done. This is necessary to trigger a completion interrupt |
| 46 | for every init interrupt before migrating the interrupt list. | 47 | for every init interrupt before migrating the interrupt list. |
| 48 | |||
| 49 | KVM_DEV_FLIC_ADAPTER_REGISTER | ||
| 50 | Register an I/O adapter interrupt source. Takes a kvm_s390_io_adapter | ||
| 51 | describing the adapter to register: | ||
| 52 | |||
| 53 | struct kvm_s390_io_adapter { | ||
| 54 | __u32 id; | ||
| 55 | __u8 isc; | ||
| 56 | __u8 maskable; | ||
| 57 | __u8 swap; | ||
| 58 | __u8 pad; | ||
| 59 | }; | ||
| 60 | |||
| 61 | id contains the unique id for the adapter, isc the I/O interruption subclass | ||
| 62 | to use, maskable whether this adapter may be masked (interrupts turned off) | ||
| 63 | and swap whether the indicators need to be byte swapped. | ||
| 64 | |||
| 65 | |||
| 66 | KVM_DEV_FLIC_ADAPTER_MODIFY | ||
| 67 | Modifies attributes of an existing I/O adapter interrupt source. Takes | ||
| 68 | a kvm_s390_io_adapter_req specifiying the adapter and the operation: | ||
| 69 | |||
| 70 | struct kvm_s390_io_adapter_req { | ||
| 71 | __u32 id; | ||
| 72 | __u8 type; | ||
| 73 | __u8 mask; | ||
| 74 | __u16 pad0; | ||
| 75 | __u64 addr; | ||
| 76 | }; | ||
| 77 | |||
| 78 | id specifies the adapter and type the operation. The supported operations | ||
| 79 | are: | ||
| 80 | |||
| 81 | KVM_S390_IO_ADAPTER_MASK | ||
| 82 | mask or unmask the adapter, as specified in mask | ||
| 83 | |||
| 84 | KVM_S390_IO_ADAPTER_MAP | ||
| 85 | perform a gmap translation for the guest address provided in addr, | ||
| 86 | pin a userspace page for the translated address and add it to the | ||
| 87 | list of mappings | ||
| 88 | |||
| 89 | KVM_S390_IO_ADAPTER_UNMAP | ||
| 90 | release a userspace page for the translated address specified in addr | ||
| 91 | from the list of mappings | ||
diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h index a995fce87791..060aaa6348d7 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h | |||
| @@ -30,16 +30,16 @@ | |||
| 30 | 30 | ||
| 31 | 31 | ||
| 32 | /* Special address that contains the comm page, used for reducing # of traps */ | 32 | /* Special address that contains the comm page, used for reducing # of traps */ |
| 33 | #define KVM_GUEST_COMMPAGE_ADDR 0x0 | 33 | #define KVM_GUEST_COMMPAGE_ADDR 0x0 |
| 34 | 34 | ||
| 35 | #define KVM_GUEST_KERNEL_MODE(vcpu) ((kvm_read_c0_guest_status(vcpu->arch.cop0) & (ST0_EXL | ST0_ERL)) || \ | 35 | #define KVM_GUEST_KERNEL_MODE(vcpu) ((kvm_read_c0_guest_status(vcpu->arch.cop0) & (ST0_EXL | ST0_ERL)) || \ |
| 36 | ((kvm_read_c0_guest_status(vcpu->arch.cop0) & KSU_USER) == 0)) | 36 | ((kvm_read_c0_guest_status(vcpu->arch.cop0) & KSU_USER) == 0)) |
| 37 | 37 | ||
| 38 | #define KVM_GUEST_KUSEG 0x00000000UL | 38 | #define KVM_GUEST_KUSEG 0x00000000UL |
| 39 | #define KVM_GUEST_KSEG0 0x40000000UL | 39 | #define KVM_GUEST_KSEG0 0x40000000UL |
| 40 | #define KVM_GUEST_KSEG23 0x60000000UL | 40 | #define KVM_GUEST_KSEG23 0x60000000UL |
| 41 | #define KVM_GUEST_KSEGX(a) ((_ACAST32_(a)) & 0x60000000) | 41 | #define KVM_GUEST_KSEGX(a) ((_ACAST32_(a)) & 0x60000000) |
| 42 | #define KVM_GUEST_CPHYSADDR(a) ((_ACAST32_(a)) & 0x1fffffff) | 42 | #define KVM_GUEST_CPHYSADDR(a) ((_ACAST32_(a)) & 0x1fffffff) |
| 43 | 43 | ||
| 44 | #define KVM_GUEST_CKSEG0ADDR(a) (KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG0) | 44 | #define KVM_GUEST_CKSEG0ADDR(a) (KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG0) |
| 45 | #define KVM_GUEST_CKSEG1ADDR(a) (KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG1) | 45 | #define KVM_GUEST_CKSEG1ADDR(a) (KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG1) |
| @@ -52,17 +52,17 @@ | |||
| 52 | #define KVM_GUEST_KSEG1ADDR(a) (KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG1) | 52 | #define KVM_GUEST_KSEG1ADDR(a) (KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG1) |
| 53 | #define KVM_GUEST_KSEG23ADDR(a) (KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG23) | 53 | #define KVM_GUEST_KSEG23ADDR(a) (KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG23) |
| 54 | 54 | ||
| 55 | #define KVM_INVALID_PAGE 0xdeadbeef | 55 | #define KVM_INVALID_PAGE 0xdeadbeef |
| 56 | #define KVM_INVALID_INST 0xdeadbeef | 56 | #define KVM_INVALID_INST 0xdeadbeef |
| 57 | #define KVM_INVALID_ADDR 0xdeadbeef | 57 | #define KVM_INVALID_ADDR 0xdeadbeef |
| 58 | 58 | ||
| 59 | #define KVM_MALTA_GUEST_RTC_ADDR 0xb8000070UL | 59 | #define KVM_MALTA_GUEST_RTC_ADDR 0xb8000070UL |
| 60 | 60 | ||
| 61 | #define GUEST_TICKS_PER_JIFFY (40000000/HZ) | 61 | #define GUEST_TICKS_PER_JIFFY (40000000/HZ) |
| 62 | #define MS_TO_NS(x) (x * 1E6L) | 62 | #define MS_TO_NS(x) (x * 1E6L) |
| 63 | 63 | ||
| 64 | #define CAUSEB_DC 27 | 64 | #define CAUSEB_DC 27 |
| 65 | #define CAUSEF_DC (_ULCAST_(1) << 27) | 65 | #define CAUSEF_DC (_ULCAST_(1) << 27) |
| 66 | 66 | ||
| 67 | struct kvm; | 67 | struct kvm; |
| 68 | struct kvm_run; | 68 | struct kvm_run; |
| @@ -126,8 +126,8 @@ struct kvm_arch { | |||
| 126 | int commpage_tlb; | 126 | int commpage_tlb; |
| 127 | }; | 127 | }; |
| 128 | 128 | ||
| 129 | #define N_MIPS_COPROC_REGS 32 | 129 | #define N_MIPS_COPROC_REGS 32 |
| 130 | #define N_MIPS_COPROC_SEL 8 | 130 | #define N_MIPS_COPROC_SEL 8 |
| 131 | 131 | ||
| 132 | struct mips_coproc { | 132 | struct mips_coproc { |
| 133 | unsigned long reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL]; | 133 | unsigned long reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL]; |
| @@ -139,124 +139,124 @@ struct mips_coproc { | |||
| 139 | /* | 139 | /* |
| 140 | * Coprocessor 0 register names | 140 | * Coprocessor 0 register names |
| 141 | */ | 141 | */ |
| 142 | #define MIPS_CP0_TLB_INDEX 0 | 142 | #define MIPS_CP0_TLB_INDEX 0 |
| 143 | #define MIPS_CP0_TLB_RANDOM 1 | 143 | #define MIPS_CP0_TLB_RANDOM 1 |
| 144 | #define MIPS_CP0_TLB_LOW 2 | 144 | #define MIPS_CP0_TLB_LOW 2 |
| 145 | #define MIPS_CP0_TLB_LO0 2 | 145 | #define MIPS_CP0_TLB_LO0 2 |
| 146 | #define MIPS_CP0_TLB_LO1 3 | 146 | #define MIPS_CP0_TLB_LO1 3 |
| 147 | #define MIPS_CP0_TLB_CONTEXT 4 | 147 | #define MIPS_CP0_TLB_CONTEXT 4 |
| 148 | #define MIPS_CP0_TLB_PG_MASK 5 | 148 | #define MIPS_CP0_TLB_PG_MASK 5 |
| 149 | #define MIPS_CP0_TLB_WIRED 6 | 149 | #define MIPS_CP0_TLB_WIRED 6 |
| 150 | #define MIPS_CP0_HWRENA 7 | 150 | #define MIPS_CP0_HWRENA 7 |
| 151 | #define MIPS_CP0_BAD_VADDR 8 | 151 | #define MIPS_CP0_BAD_VADDR 8 |
| 152 | #define MIPS_CP0_COUNT 9 | 152 | #define MIPS_CP0_COUNT 9 |
| 153 | #define MIPS_CP0_TLB_HI 10 | 153 | #define MIPS_CP0_TLB_HI 10 |
| 154 | #define MIPS_CP0_COMPARE 11 | 154 | #define MIPS_CP0_COMPARE 11 |
| 155 | #define MIPS_CP0_STATUS 12 | 155 | #define MIPS_CP0_STATUS 12 |
| 156 | #define MIPS_CP0_CAUSE 13 | 156 | #define MIPS_CP0_CAUSE 13 |
| 157 | #define MIPS_CP0_EXC_PC 14 | 157 | #define MIPS_CP0_EXC_PC 14 |
| 158 | #define MIPS_CP0_PRID 15 | 158 | #define MIPS_CP0_PRID 15 |
| 159 | #define MIPS_CP0_CONFIG 16 | 159 | #define MIPS_CP0_CONFIG 16 |
| 160 | #define MIPS_CP0_LLADDR 17 | 160 | #define MIPS_CP0_LLADDR 17 |
| 161 | #define MIPS_CP0_WATCH_LO 18 | 161 | #define MIPS_CP0_WATCH_LO 18 |
| 162 | #define MIPS_CP0_WATCH_HI 19 | 162 | #define MIPS_CP0_WATCH_HI 19 |
| 163 | #define MIPS_CP0_TLB_XCONTEXT 20 | 163 | #define MIPS_CP0_TLB_XCONTEXT 20 |
| 164 | #define MIPS_CP0_ECC 26 | 164 | #define MIPS_CP0_ECC 26 |
| 165 | #define MIPS_CP0_CACHE_ERR 27 | 165 | #define MIPS_CP0_CACHE_ERR 27 |
| 166 | #define MIPS_CP0_TAG_LO 28 | 166 | #define MIPS_CP0_TAG_LO 28 |
| 167 | #define MIPS_CP0_TAG_HI 29 | 167 | #define MIPS_CP0_TAG_HI 29 |
| 168 | #define MIPS_CP0_ERROR_PC 30 | 168 | #define MIPS_CP0_ERROR_PC 30 |
| 169 | #define MIPS_CP0_DEBUG 23 | 169 | #define MIPS_CP0_DEBUG 23 |
| 170 | #define MIPS_CP0_DEPC 24 | 170 | #define MIPS_CP0_DEPC 24 |
| 171 | #define MIPS_CP0_PERFCNT 25 | 171 | #define MIPS_CP0_PERFCNT 25 |
| 172 | #define MIPS_CP0_ERRCTL 26 | 172 | #define MIPS_CP0_ERRCTL 26 |
| 173 | #define MIPS_CP0_DATA_LO 28 | 173 | #define MIPS_CP0_DATA_LO 28 |
| 174 | #define MIPS_CP0_DATA_HI 29 | 174 | #define MIPS_CP0_DATA_HI 29 |
| 175 | #define MIPS_CP0_DESAVE 31 | 175 | #define MIPS_CP0_DESAVE 31 |
| 176 | 176 | ||
| 177 | #define MIPS_CP0_CONFIG_SEL 0 | 177 | #define MIPS_CP0_CONFIG_SEL 0 |
| 178 | #define MIPS_CP0_CONFIG1_SEL 1 | 178 | #define MIPS_CP0_CONFIG1_SEL 1 |
| 179 | #define MIPS_CP0_CONFIG2_SEL 2 | 179 | #define MIPS_CP0_CONFIG2_SEL 2 |
| 180 | #define MIPS_CP0_CONFIG3_SEL 3 | 180 | #define MIPS_CP0_CONFIG3_SEL 3 |
| 181 | 181 | ||
| 182 | /* Config0 register bits */ | 182 | /* Config0 register bits */ |
| 183 | #define CP0C0_M 31 | 183 | #define CP0C0_M 31 |
| 184 | #define CP0C0_K23 28 | 184 | #define CP0C0_K23 28 |
| 185 | #define CP0C0_KU 25 | 185 | #define CP0C0_KU 25 |
| 186 | #define CP0C0_MDU 20 | 186 | #define CP0C0_MDU 20 |
| 187 | #define CP0C0_MM 17 | 187 | #define CP0C0_MM 17 |
| 188 | #define CP0C0_BM 16 | 188 | #define CP0C0_BM 16 |
| 189 | #define CP0C0_BE 15 | 189 | #define CP0C0_BE 15 |
| 190 | #define CP0C0_AT 13 | 190 | #define CP0C0_AT 13 |
| 191 | #define CP0C0_AR 10 | 191 | #define CP0C0_AR 10 |
| 192 | #define CP0C0_MT 7 | 192 | #define CP0C0_MT 7 |
| 193 | #define CP0C0_VI 3 | 193 | #define CP0C0_VI 3 |
| 194 | #define CP0C0_K0 0 | 194 | #define CP0C0_K0 0 |
| 195 | 195 | ||
| 196 | /* Config1 register bits */ | 196 | /* Config1 register bits */ |
| 197 | #define CP0C1_M 31 | 197 | #define CP0C1_M 31 |
| 198 | #define CP0C1_MMU 25 | 198 | #define CP0C1_MMU 25 |
| 199 | #define CP0C1_IS 22 | 199 | #define CP0C1_IS 22 |
| 200 | #define CP0C1_IL 19 | 200 | #define CP0C1_IL 19 |
| 201 | #define CP0C1_IA 16 | 201 | #define CP0C1_IA 16 |
| 202 | #define CP0C1_DS 13 | 202 | #define CP0C1_DS 13 |
| 203 | #define CP0C1_DL 10 | 203 | #define CP0C1_DL 10 |
| 204 | #define CP0C1_DA 7 | 204 | #define CP0C1_DA 7 |
| 205 | #define CP0C1_C2 6 | 205 | #define CP0C1_C2 6 |
| 206 | #define CP0C1_MD 5 | 206 | #define CP0C1_MD 5 |
| 207 | #define CP0C1_PC 4 | 207 | #define CP0C1_PC 4 |
| 208 | #define CP0C1_WR 3 | 208 | #define CP0C1_WR 3 |
| 209 | #define CP0C1_CA 2 | 209 | #define CP0C1_CA 2 |
| 210 | #define CP0C1_EP 1 | 210 | #define CP0C1_EP 1 |
| 211 | #define CP0C1_FP 0 | 211 | #define CP0C1_FP 0 |
| 212 | 212 | ||
| 213 | /* Config2 Register bits */ | 213 | /* Config2 Register bits */ |
| 214 | #define CP0C2_M 31 | 214 | #define CP0C2_M 31 |
| 215 | #define CP0C2_TU 28 | 215 | #define CP0C2_TU 28 |
| 216 | #define CP0C2_TS 24 | 216 | #define CP0C2_TS 24 |
| 217 | #define CP0C2_TL 20 | 217 | #define CP0C2_TL 20 |
| 218 | #define CP0C2_TA 16 | 218 | #define CP0C2_TA 16 |
| 219 | #define CP0C2_SU 12 | 219 | #define CP0C2_SU 12 |
| 220 | #define CP0C2_SS 8 | 220 | #define CP0C2_SS 8 |
| 221 | #define CP0C2_SL 4 | 221 | #define CP0C2_SL 4 |
| 222 | #define CP0C2_SA 0 | 222 | #define CP0C2_SA 0 |
| 223 | 223 | ||
| 224 | /* Config3 Register bits */ | 224 | /* Config3 Register bits */ |
| 225 | #define CP0C3_M 31 | 225 | #define CP0C3_M 31 |
| 226 | #define CP0C3_ISA_ON_EXC 16 | 226 | #define CP0C3_ISA_ON_EXC 16 |
| 227 | #define CP0C3_ULRI 13 | 227 | #define CP0C3_ULRI 13 |
| 228 | #define CP0C3_DSPP 10 | 228 | #define CP0C3_DSPP 10 |
| 229 | #define CP0C3_LPA 7 | 229 | #define CP0C3_LPA 7 |
| 230 | #define CP0C3_VEIC 6 | 230 | #define CP0C3_VEIC 6 |
| 231 | #define CP0C3_VInt 5 | 231 | #define CP0C3_VInt 5 |
| 232 | #define CP0C3_SP 4 | 232 | #define CP0C3_SP 4 |
| 233 | #define CP0C3_MT 2 | 233 | #define CP0C3_MT 2 |
| 234 | #define CP0C3_SM 1 | 234 | #define CP0C3_SM 1 |
| 235 | #define CP0C3_TL 0 | 235 | #define CP0C3_TL 0 |
| 236 | 236 | ||
| 237 | /* Have config1, Cacheable, noncoherent, write-back, write allocate*/ | 237 | /* Have config1, Cacheable, noncoherent, write-back, write allocate*/ |
| 238 | #define MIPS_CONFIG0 \ | 238 | #define MIPS_CONFIG0 \ |
| 239 | ((1 << CP0C0_M) | (0x3 << CP0C0_K0)) | 239 | ((1 << CP0C0_M) | (0x3 << CP0C0_K0)) |
| 240 | 240 | ||
| 241 | /* Have config2, no coprocessor2 attached, no MDMX support attached, | 241 | /* Have config2, no coprocessor2 attached, no MDMX support attached, |
| 242 | no performance counters, watch registers present, | 242 | no performance counters, watch registers present, |
| 243 | no code compression, EJTAG present, no FPU, no watch registers */ | 243 | no code compression, EJTAG present, no FPU, no watch registers */ |
| 244 | #define MIPS_CONFIG1 \ | 244 | #define MIPS_CONFIG1 \ |
| 245 | ((1 << CP0C1_M) | \ | 245 | ((1 << CP0C1_M) | \ |
| 246 | (0 << CP0C1_C2) | (0 << CP0C1_MD) | (0 << CP0C1_PC) | \ | 246 | (0 << CP0C1_C2) | (0 << CP0C1_MD) | (0 << CP0C1_PC) | \ |
| 247 | (0 << CP0C1_WR) | (0 << CP0C1_CA) | (1 << CP0C1_EP) | \ | 247 | (0 << CP0C1_WR) | (0 << CP0C1_CA) | (1 << CP0C1_EP) | \ |
| 248 | (0 << CP0C1_FP)) | 248 | (0 << CP0C1_FP)) |
| 249 | 249 | ||
| 250 | /* Have config3, no tertiary/secondary caches implemented */ | 250 | /* Have config3, no tertiary/secondary caches implemented */ |
| 251 | #define MIPS_CONFIG2 \ | 251 | #define MIPS_CONFIG2 \ |
| 252 | ((1 << CP0C2_M)) | 252 | ((1 << CP0C2_M)) |
| 253 | 253 | ||
| 254 | /* No config4, no DSP ASE, no large physaddr (PABITS), | 254 | /* No config4, no DSP ASE, no large physaddr (PABITS), |
| 255 | no external interrupt controller, no vectored interrupts, | 255 | no external interrupt controller, no vectored interrupts, |
| 256 | no 1kb pages, no SmartMIPS ASE, no trace logic */ | 256 | no 1kb pages, no SmartMIPS ASE, no trace logic */ |
| 257 | #define MIPS_CONFIG3 \ | 257 | #define MIPS_CONFIG3 \ |
| 258 | ((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) | \ | 258 | ((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) | \ |
| 259 | (0 << CP0C3_VEIC) | (0 << CP0C3_VInt) | (0 << CP0C3_SP) | \ | 259 | (0 << CP0C3_VEIC) | (0 << CP0C3_VInt) | (0 << CP0C3_SP) | \ |
| 260 | (0 << CP0C3_SM) | (0 << CP0C3_TL)) | 260 | (0 << CP0C3_SM) | (0 << CP0C3_TL)) |
| 261 | 261 | ||
| 262 | /* MMU types, the first four entries have the same layout as the | 262 | /* MMU types, the first four entries have the same layout as the |
| @@ -274,36 +274,36 @@ enum mips_mmu_types { | |||
| 274 | /* | 274 | /* |
| 275 | * Trap codes | 275 | * Trap codes |
| 276 | */ | 276 | */ |
| 277 | #define T_INT 0 /* Interrupt pending */ | 277 | #define T_INT 0 /* Interrupt pending */ |
| 278 | #define T_TLB_MOD 1 /* TLB modified fault */ | 278 | #define T_TLB_MOD 1 /* TLB modified fault */ |
| 279 | #define T_TLB_LD_MISS 2 /* TLB miss on load or ifetch */ | 279 | #define T_TLB_LD_MISS 2 /* TLB miss on load or ifetch */ |
| 280 | #define T_TLB_ST_MISS 3 /* TLB miss on a store */ | 280 | #define T_TLB_ST_MISS 3 /* TLB miss on a store */ |
| 281 | #define T_ADDR_ERR_LD 4 /* Address error on a load or ifetch */ | 281 | #define T_ADDR_ERR_LD 4 /* Address error on a load or ifetch */ |
| 282 | #define T_ADDR_ERR_ST 5 /* Address error on a store */ | 282 | #define T_ADDR_ERR_ST 5 /* Address error on a store */ |
| 283 | #define T_BUS_ERR_IFETCH 6 /* Bus error on an ifetch */ | 283 | #define T_BUS_ERR_IFETCH 6 /* Bus error on an ifetch */ |
| 284 | #define T_BUS_ERR_LD_ST 7 /* Bus error on a load or store */ | 284 | #define T_BUS_ERR_LD_ST 7 /* Bus error on a load or store */ |
| 285 | #define T_SYSCALL 8 /* System call */ | 285 | #define T_SYSCALL 8 /* System call */ |
| 286 | #define T_BREAK 9 /* Breakpoint */ | 286 | #define T_BREAK 9 /* Breakpoint */ |
| 287 | #define T_RES_INST 10 /* Reserved instruction exception */ | 287 | #define T_RES_INST 10 /* Reserved instruction exception */ |
| 288 | #define T_COP_UNUSABLE 11 /* Coprocessor unusable */ | 288 | #define T_COP_UNUSABLE 11 /* Coprocessor unusable */ |
| 289 | #define T_OVFLOW 12 /* Arithmetic overflow */ | 289 | #define T_OVFLOW 12 /* Arithmetic overflow */ |
| 290 | 290 | ||
| 291 | /* | 291 | /* |
| 292 | * Trap definitions added for r4000 port. | 292 | * Trap definitions added for r4000 port. |
| 293 | */ | 293 | */ |
| 294 | #define T_TRAP 13 /* Trap instruction */ | 294 | #define T_TRAP 13 /* Trap instruction */ |
| 295 | #define T_VCEI 14 /* Virtual coherency exception */ | 295 | #define T_VCEI 14 /* Virtual coherency exception */ |
| 296 | #define T_FPE 15 /* Floating point exception */ | 296 | #define T_FPE 15 /* Floating point exception */ |
| 297 | #define T_WATCH 23 /* Watch address reference */ | 297 | #define T_WATCH 23 /* Watch address reference */ |
| 298 | #define T_VCED 31 /* Virtual coherency data */ | 298 | #define T_VCED 31 /* Virtual coherency data */ |
| 299 | 299 | ||
| 300 | /* Resume Flags */ | 300 | /* Resume Flags */ |
| 301 | #define RESUME_FLAG_DR (1<<0) /* Reload guest nonvolatile state? */ | 301 | #define RESUME_FLAG_DR (1<<0) /* Reload guest nonvolatile state? */ |
| 302 | #define RESUME_FLAG_HOST (1<<1) /* Resume host? */ | 302 | #define RESUME_FLAG_HOST (1<<1) /* Resume host? */ |
| 303 | 303 | ||
| 304 | #define RESUME_GUEST 0 | 304 | #define RESUME_GUEST 0 |
| 305 | #define RESUME_GUEST_DR RESUME_FLAG_DR | 305 | #define RESUME_GUEST_DR RESUME_FLAG_DR |
| 306 | #define RESUME_HOST RESUME_FLAG_HOST | 306 | #define RESUME_HOST RESUME_FLAG_HOST |
| 307 | 307 | ||
| 308 | enum emulation_result { | 308 | enum emulation_result { |
| 309 | EMULATE_DONE, /* no further processing */ | 309 | EMULATE_DONE, /* no further processing */ |
| @@ -313,24 +313,27 @@ enum emulation_result { | |||
| 313 | EMULATE_PRIV_FAIL, | 313 | EMULATE_PRIV_FAIL, |
| 314 | }; | 314 | }; |
| 315 | 315 | ||
| 316 | #define MIPS3_PG_G 0x00000001 /* Global; ignore ASID if in lo0 & lo1 */ | 316 | #define MIPS3_PG_G 0x00000001 /* Global; ignore ASID if in lo0 & lo1 */ |
| 317 | #define MIPS3_PG_V 0x00000002 /* Valid */ | 317 | #define MIPS3_PG_V 0x00000002 /* Valid */ |
| 318 | #define MIPS3_PG_NV 0x00000000 | 318 | #define MIPS3_PG_NV 0x00000000 |
| 319 | #define MIPS3_PG_D 0x00000004 /* Dirty */ | 319 | #define MIPS3_PG_D 0x00000004 /* Dirty */ |
| 320 | 320 | ||
| 321 | #define mips3_paddr_to_tlbpfn(x) \ | 321 | #define mips3_paddr_to_tlbpfn(x) \ |
| 322 | (((unsigned long)(x) >> MIPS3_PG_SHIFT) & MIPS3_PG_FRAME) | 322 | (((unsigned long)(x) >> MIPS3_PG_SHIFT) & MIPS3_PG_FRAME) |
| 323 | #define mips3_tlbpfn_to_paddr(x) \ | 323 | #define mips3_tlbpfn_to_paddr(x) \ |
| 324 | ((unsigned long)((x) & MIPS3_PG_FRAME) << MIPS3_PG_SHIFT) | 324 | ((unsigned long)((x) & MIPS3_PG_FRAME) << MIPS3_PG_SHIFT) |
| 325 | 325 | ||
| 326 | #define MIPS3_PG_SHIFT 6 | 326 | #define MIPS3_PG_SHIFT 6 |
| 327 | #define MIPS3_PG_FRAME 0x3fffffc0 | 327 | #define MIPS3_PG_FRAME 0x3fffffc0 |
| 328 | 328 | ||
| 329 | #define VPN2_MASK 0xffffe000 | 329 | #define VPN2_MASK 0xffffe000 |
| 330 | #define TLB_IS_GLOBAL(x) (((x).tlb_lo0 & MIPS3_PG_G) && ((x).tlb_lo1 & MIPS3_PG_G)) | 330 | #define TLB_IS_GLOBAL(x) (((x).tlb_lo0 & MIPS3_PG_G) && \ |
| 331 | #define TLB_VPN2(x) ((x).tlb_hi & VPN2_MASK) | 331 | ((x).tlb_lo1 & MIPS3_PG_G)) |
| 332 | #define TLB_ASID(x) ((x).tlb_hi & ASID_MASK) | 332 | #define TLB_VPN2(x) ((x).tlb_hi & VPN2_MASK) |
| 333 | #define TLB_IS_VALID(x, va) (((va) & (1 << PAGE_SHIFT)) ? ((x).tlb_lo1 & MIPS3_PG_V) : ((x).tlb_lo0 & MIPS3_PG_V)) | 333 | #define TLB_ASID(x) ((x).tlb_hi & ASID_MASK) |
| 334 | #define TLB_IS_VALID(x, va) (((va) & (1 << PAGE_SHIFT)) \ | ||
| 335 | ? ((x).tlb_lo1 & MIPS3_PG_V) \ | ||
| 336 | : ((x).tlb_lo0 & MIPS3_PG_V)) | ||
| 334 | 337 | ||
| 335 | struct kvm_mips_tlb { | 338 | struct kvm_mips_tlb { |
| 336 | long tlb_mask; | 339 | long tlb_mask; |
| @@ -339,7 +342,7 @@ struct kvm_mips_tlb { | |||
| 339 | long tlb_lo1; | 342 | long tlb_lo1; |
| 340 | }; | 343 | }; |
| 341 | 344 | ||
| 342 | #define KVM_MIPS_GUEST_TLB_SIZE 64 | 345 | #define KVM_MIPS_GUEST_TLB_SIZE 64 |
| 343 | struct kvm_vcpu_arch { | 346 | struct kvm_vcpu_arch { |
| 344 | void *host_ebase, *guest_ebase; | 347 | void *host_ebase, *guest_ebase; |
| 345 | unsigned long host_stack; | 348 | unsigned long host_stack; |
| @@ -400,65 +403,67 @@ struct kvm_vcpu_arch { | |||
| 400 | }; | 403 | }; |
| 401 | 404 | ||
| 402 | 405 | ||
| 403 | #define kvm_read_c0_guest_index(cop0) (cop0->reg[MIPS_CP0_TLB_INDEX][0]) | 406 | #define kvm_read_c0_guest_index(cop0) (cop0->reg[MIPS_CP0_TLB_INDEX][0]) |
| 404 | #define kvm_write_c0_guest_index(cop0, val) (cop0->reg[MIPS_CP0_TLB_INDEX][0] = val) | 407 | #define kvm_write_c0_guest_index(cop0, val) (cop0->reg[MIPS_CP0_TLB_INDEX][0] = val) |
| 405 | #define kvm_read_c0_guest_entrylo0(cop0) (cop0->reg[MIPS_CP0_TLB_LO0][0]) | 408 | #define kvm_read_c0_guest_entrylo0(cop0) (cop0->reg[MIPS_CP0_TLB_LO0][0]) |
| 406 | #define kvm_read_c0_guest_entrylo1(cop0) (cop0->reg[MIPS_CP0_TLB_LO1][0]) | 409 | #define kvm_read_c0_guest_entrylo1(cop0) (cop0->reg[MIPS_CP0_TLB_LO1][0]) |
| 407 | #define kvm_read_c0_guest_context(cop0) (cop0->reg[MIPS_CP0_TLB_CONTEXT][0]) | 410 | #define kvm_read_c0_guest_context(cop0) (cop0->reg[MIPS_CP0_TLB_CONTEXT][0]) |
| 408 | #define kvm_write_c0_guest_context(cop0, val) (cop0->reg[MIPS_CP0_TLB_CONTEXT][0] = (val)) | 411 | #define kvm_write_c0_guest_context(cop0, val) (cop0->reg[MIPS_CP0_TLB_CONTEXT][0] = (val)) |
| 409 | #define kvm_read_c0_guest_userlocal(cop0) (cop0->reg[MIPS_CP0_TLB_CONTEXT][2]) | 412 | #define kvm_read_c0_guest_userlocal(cop0) (cop0->reg[MIPS_CP0_TLB_CONTEXT][2]) |
| 410 | #define kvm_read_c0_guest_pagemask(cop0) (cop0->reg[MIPS_CP0_TLB_PG_MASK][0]) | 413 | #define kvm_read_c0_guest_pagemask(cop0) (cop0->reg[MIPS_CP0_TLB_PG_MASK][0]) |
| 411 | #define kvm_write_c0_guest_pagemask(cop0, val) (cop0->reg[MIPS_CP0_TLB_PG_MASK][0] = (val)) | 414 | #define kvm_write_c0_guest_pagemask(cop0, val) (cop0->reg[MIPS_CP0_TLB_PG_MASK][0] = (val)) |
| 412 | #define kvm_read_c0_guest_wired(cop0) (cop0->reg[MIPS_CP0_TLB_WIRED][0]) | 415 | #define kvm_read_c0_guest_wired(cop0) (cop0->reg[MIPS_CP0_TLB_WIRED][0]) |
| 413 | #define kvm_write_c0_guest_wired(cop0, val) (cop0->reg[MIPS_CP0_TLB_WIRED][0] = (val)) | 416 | #define kvm_write_c0_guest_wired(cop0, val) (cop0->reg[MIPS_CP0_TLB_WIRED][0] = (val)) |
| 414 | #define kvm_read_c0_guest_badvaddr(cop0) (cop0->reg[MIPS_CP0_BAD_VADDR][0]) | 417 | #define kvm_read_c0_guest_hwrena(cop0) (cop0->reg[MIPS_CP0_HWRENA][0]) |
| 415 | #define kvm_write_c0_guest_badvaddr(cop0, val) (cop0->reg[MIPS_CP0_BAD_VADDR][0] = (val)) | 418 | #define kvm_write_c0_guest_hwrena(cop0, val) (cop0->reg[MIPS_CP0_HWRENA][0] = (val)) |
| 416 | #define kvm_read_c0_guest_count(cop0) (cop0->reg[MIPS_CP0_COUNT][0]) | 419 | #define kvm_read_c0_guest_badvaddr(cop0) (cop0->reg[MIPS_CP0_BAD_VADDR][0]) |
| 417 | #define kvm_write_c0_guest_count(cop0, val) (cop0->reg[MIPS_CP0_COUNT][0] = (val)) | 420 | #define kvm_write_c0_guest_badvaddr(cop0, val) (cop0->reg[MIPS_CP0_BAD_VADDR][0] = (val)) |
| 418 | #define kvm_read_c0_guest_entryhi(cop0) (cop0->reg[MIPS_CP0_TLB_HI][0]) | 421 | #define kvm_read_c0_guest_count(cop0) (cop0->reg[MIPS_CP0_COUNT][0]) |
| 419 | #define kvm_write_c0_guest_entryhi(cop0, val) (cop0->reg[MIPS_CP0_TLB_HI][0] = (val)) | 422 | #define kvm_write_c0_guest_count(cop0, val) (cop0->reg[MIPS_CP0_COUNT][0] = (val)) |
| 420 | #define kvm_read_c0_guest_compare(cop0) (cop0->reg[MIPS_CP0_COMPARE][0]) | 423 | #define kvm_read_c0_guest_entryhi(cop0) (cop0->reg[MIPS_CP0_TLB_HI][0]) |
| 421 | #define kvm_write_c0_guest_compare(cop0, val) (cop0->reg[MIPS_CP0_COMPARE][0] = (val)) | 424 | #define kvm_write_c0_guest_entryhi(cop0, val) (cop0->reg[MIPS_CP0_TLB_HI][0] = (val)) |
| 422 | #define kvm_read_c0_guest_status(cop0) (cop0->reg[MIPS_CP0_STATUS][0]) | 425 | #define kvm_read_c0_guest_compare(cop0) (cop0->reg[MIPS_CP0_COMPARE][0]) |
| 423 | #define kvm_write_c0_guest_status(cop0, val) (cop0->reg[MIPS_CP0_STATUS][0] = (val)) | 426 | #define kvm_write_c0_guest_compare(cop0, val) (cop0->reg[MIPS_CP0_COMPARE][0] = (val)) |
| 424 | #define kvm_read_c0_guest_intctl(cop0) (cop0->reg[MIPS_CP0_STATUS][1]) | 427 | #define kvm_read_c0_guest_status(cop0) (cop0->reg[MIPS_CP0_STATUS][0]) |
| 425 | #define kvm_write_c0_guest_intctl(cop0, val) (cop0->reg[MIPS_CP0_STATUS][1] = (val)) | 428 | #define kvm_write_c0_guest_status(cop0, val) (cop0->reg[MIPS_CP0_STATUS][0] = (val)) |
| 426 | #define kvm_read_c0_guest_cause(cop0) (cop0->reg[MIPS_CP0_CAUSE][0]) | 429 | #define kvm_read_c0_guest_intctl(cop0) (cop0->reg[MIPS_CP0_STATUS][1]) |
| 427 | #define kvm_write_c0_guest_cause(cop0, val) (cop0->reg[MIPS_CP0_CAUSE][0] = (val)) | 430 | #define kvm_write_c0_guest_intctl(cop0, val) (cop0->reg[MIPS_CP0_STATUS][1] = (val)) |
| 428 | #define kvm_read_c0_guest_epc(cop0) (cop0->reg[MIPS_CP0_EXC_PC][0]) | 431 | #define kvm_read_c0_guest_cause(cop0) (cop0->reg[MIPS_CP0_CAUSE][0]) |
| 429 | #define kvm_write_c0_guest_epc(cop0, val) (cop0->reg[MIPS_CP0_EXC_PC][0] = (val)) | 432 | #define kvm_write_c0_guest_cause(cop0, val) (cop0->reg[MIPS_CP0_CAUSE][0] = (val)) |
| 430 | #define kvm_read_c0_guest_prid(cop0) (cop0->reg[MIPS_CP0_PRID][0]) | 433 | #define kvm_read_c0_guest_epc(cop0) (cop0->reg[MIPS_CP0_EXC_PC][0]) |
| 431 | #define kvm_write_c0_guest_prid(cop0, val) (cop0->reg[MIPS_CP0_PRID][0] = (val)) | 434 | #define kvm_write_c0_guest_epc(cop0, val) (cop0->reg[MIPS_CP0_EXC_PC][0] = (val)) |
| 432 | #define kvm_read_c0_guest_ebase(cop0) (cop0->reg[MIPS_CP0_PRID][1]) | 435 | #define kvm_read_c0_guest_prid(cop0) (cop0->reg[MIPS_CP0_PRID][0]) |
| 433 | #define kvm_write_c0_guest_ebase(cop0, val) (cop0->reg[MIPS_CP0_PRID][1] = (val)) | 436 | #define kvm_write_c0_guest_prid(cop0, val) (cop0->reg[MIPS_CP0_PRID][0] = (val)) |
| 434 | #define kvm_read_c0_guest_config(cop0) (cop0->reg[MIPS_CP0_CONFIG][0]) | 437 | #define kvm_read_c0_guest_ebase(cop0) (cop0->reg[MIPS_CP0_PRID][1]) |
| 435 | #define kvm_read_c0_guest_config1(cop0) (cop0->reg[MIPS_CP0_CONFIG][1]) | 438 | #define kvm_write_c0_guest_ebase(cop0, val) (cop0->reg[MIPS_CP0_PRID][1] = (val)) |
| 436 | #define kvm_read_c0_guest_config2(cop0) (cop0->reg[MIPS_CP0_CONFIG][2]) | 439 | #define kvm_read_c0_guest_config(cop0) (cop0->reg[MIPS_CP0_CONFIG][0]) |
| 437 | #define kvm_read_c0_guest_config3(cop0) (cop0->reg[MIPS_CP0_CONFIG][3]) | 440 | #define kvm_read_c0_guest_config1(cop0) (cop0->reg[MIPS_CP0_CONFIG][1]) |
| 438 | #define kvm_read_c0_guest_config7(cop0) (cop0->reg[MIPS_CP0_CONFIG][7]) | 441 | #define kvm_read_c0_guest_config2(cop0) (cop0->reg[MIPS_CP0_CONFIG][2]) |
| 439 | #define kvm_write_c0_guest_config(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][0] = (val)) | 442 | #define kvm_read_c0_guest_config3(cop0) (cop0->reg[MIPS_CP0_CONFIG][3]) |
| 440 | #define kvm_write_c0_guest_config1(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][1] = (val)) | 443 | #define kvm_read_c0_guest_config7(cop0) (cop0->reg[MIPS_CP0_CONFIG][7]) |
| 441 | #define kvm_write_c0_guest_config2(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][2] = (val)) | 444 | #define kvm_write_c0_guest_config(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][0] = (val)) |
| 442 | #define kvm_write_c0_guest_config3(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][3] = (val)) | 445 | #define kvm_write_c0_guest_config1(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][1] = (val)) |
| 443 | #define kvm_write_c0_guest_config7(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][7] = (val)) | 446 | #define kvm_write_c0_guest_config2(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][2] = (val)) |
| 444 | #define kvm_read_c0_guest_errorepc(cop0) (cop0->reg[MIPS_CP0_ERROR_PC][0]) | 447 | #define kvm_write_c0_guest_config3(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][3] = (val)) |
| 445 | #define kvm_write_c0_guest_errorepc(cop0, val) (cop0->reg[MIPS_CP0_ERROR_PC][0] = (val)) | 448 | #define kvm_write_c0_guest_config7(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][7] = (val)) |
| 446 | 449 | #define kvm_read_c0_guest_errorepc(cop0) (cop0->reg[MIPS_CP0_ERROR_PC][0]) | |
| 447 | #define kvm_set_c0_guest_status(cop0, val) (cop0->reg[MIPS_CP0_STATUS][0] |= (val)) | 450 | #define kvm_write_c0_guest_errorepc(cop0, val) (cop0->reg[MIPS_CP0_ERROR_PC][0] = (val)) |
| 448 | #define kvm_clear_c0_guest_status(cop0, val) (cop0->reg[MIPS_CP0_STATUS][0] &= ~(val)) | 451 | |
| 449 | #define kvm_set_c0_guest_cause(cop0, val) (cop0->reg[MIPS_CP0_CAUSE][0] |= (val)) | 452 | #define kvm_set_c0_guest_status(cop0, val) (cop0->reg[MIPS_CP0_STATUS][0] |= (val)) |
| 450 | #define kvm_clear_c0_guest_cause(cop0, val) (cop0->reg[MIPS_CP0_CAUSE][0] &= ~(val)) | 453 | #define kvm_clear_c0_guest_status(cop0, val) (cop0->reg[MIPS_CP0_STATUS][0] &= ~(val)) |
| 451 | #define kvm_change_c0_guest_cause(cop0, change, val) \ | 454 | #define kvm_set_c0_guest_cause(cop0, val) (cop0->reg[MIPS_CP0_CAUSE][0] |= (val)) |
| 452 | { \ | 455 | #define kvm_clear_c0_guest_cause(cop0, val) (cop0->reg[MIPS_CP0_CAUSE][0] &= ~(val)) |
| 453 | kvm_clear_c0_guest_cause(cop0, change); \ | 456 | #define kvm_change_c0_guest_cause(cop0, change, val) \ |
| 454 | kvm_set_c0_guest_cause(cop0, ((val) & (change))); \ | 457 | { \ |
| 458 | kvm_clear_c0_guest_cause(cop0, change); \ | ||
| 459 | kvm_set_c0_guest_cause(cop0, ((val) & (change))); \ | ||
| 455 | } | 460 | } |
| 456 | #define kvm_set_c0_guest_ebase(cop0, val) (cop0->reg[MIPS_CP0_PRID][1] |= (val)) | 461 | #define kvm_set_c0_guest_ebase(cop0, val) (cop0->reg[MIPS_CP0_PRID][1] |= (val)) |
| 457 | #define kvm_clear_c0_guest_ebase(cop0, val) (cop0->reg[MIPS_CP0_PRID][1] &= ~(val)) | 462 | #define kvm_clear_c0_guest_ebase(cop0, val) (cop0->reg[MIPS_CP0_PRID][1] &= ~(val)) |
| 458 | #define kvm_change_c0_guest_ebase(cop0, change, val) \ | 463 | #define kvm_change_c0_guest_ebase(cop0, change, val) \ |
| 459 | { \ | 464 | { \ |
| 460 | kvm_clear_c0_guest_ebase(cop0, change); \ | 465 | kvm_clear_c0_guest_ebase(cop0, change); \ |
| 461 | kvm_set_c0_guest_ebase(cop0, ((val) & (change))); \ | 466 | kvm_set_c0_guest_ebase(cop0, ((val) & (change))); \ |
| 462 | } | 467 | } |
| 463 | 468 | ||
| 464 | 469 | ||
diff --git a/arch/mips/kvm/kvm_mips_emul.c b/arch/mips/kvm/kvm_mips_emul.c index 4b6274b47f33..e3fec99941a7 100644 --- a/arch/mips/kvm/kvm_mips_emul.c +++ b/arch/mips/kvm/kvm_mips_emul.c | |||
| @@ -436,13 +436,6 @@ kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc, uint32_t cause, | |||
| 436 | sel = inst & 0x7; | 436 | sel = inst & 0x7; |
| 437 | co_bit = (inst >> 25) & 1; | 437 | co_bit = (inst >> 25) & 1; |
| 438 | 438 | ||
| 439 | /* Verify that the register is valid */ | ||
| 440 | if (rd > MIPS_CP0_DESAVE) { | ||
| 441 | printk("Invalid rd: %d\n", rd); | ||
| 442 | er = EMULATE_FAIL; | ||
| 443 | goto done; | ||
| 444 | } | ||
| 445 | |||
| 446 | if (co_bit) { | 439 | if (co_bit) { |
| 447 | op = (inst) & 0xff; | 440 | op = (inst) & 0xff; |
| 448 | 441 | ||
| @@ -1542,8 +1535,15 @@ kvm_mips_handle_ri(unsigned long cause, uint32_t *opc, | |||
| 1542 | } | 1535 | } |
| 1543 | 1536 | ||
| 1544 | if ((inst & OPCODE) == SPEC3 && (inst & FUNC) == RDHWR) { | 1537 | if ((inst & OPCODE) == SPEC3 && (inst & FUNC) == RDHWR) { |
| 1538 | int usermode = !KVM_GUEST_KERNEL_MODE(vcpu); | ||
| 1545 | int rd = (inst & RD) >> 11; | 1539 | int rd = (inst & RD) >> 11; |
| 1546 | int rt = (inst & RT) >> 16; | 1540 | int rt = (inst & RT) >> 16; |
| 1541 | /* If usermode, check RDHWR rd is allowed by guest HWREna */ | ||
| 1542 | if (usermode && !(kvm_read_c0_guest_hwrena(cop0) & BIT(rd))) { | ||
| 1543 | kvm_debug("RDHWR %#x disallowed by HWREna @ %p\n", | ||
| 1544 | rd, opc); | ||
| 1545 | goto emulate_ri; | ||
| 1546 | } | ||
| 1547 | switch (rd) { | 1547 | switch (rd) { |
| 1548 | case 0: /* CPU number */ | 1548 | case 0: /* CPU number */ |
| 1549 | arch->gprs[rt] = 0; | 1549 | arch->gprs[rt] = 0; |
| @@ -1567,31 +1567,27 @@ kvm_mips_handle_ri(unsigned long cause, uint32_t *opc, | |||
| 1567 | } | 1567 | } |
| 1568 | break; | 1568 | break; |
| 1569 | case 29: | 1569 | case 29: |
| 1570 | #if 1 | ||
| 1571 | arch->gprs[rt] = kvm_read_c0_guest_userlocal(cop0); | 1570 | arch->gprs[rt] = kvm_read_c0_guest_userlocal(cop0); |
| 1572 | #else | ||
| 1573 | /* UserLocal not implemented */ | ||
| 1574 | er = kvm_mips_emulate_ri_exc(cause, opc, run, vcpu); | ||
| 1575 | #endif | ||
| 1576 | break; | 1571 | break; |
| 1577 | 1572 | ||
| 1578 | default: | 1573 | default: |
| 1579 | printk("RDHWR not supported\n"); | 1574 | kvm_debug("RDHWR %#x not supported @ %p\n", rd, opc); |
| 1580 | er = EMULATE_FAIL; | 1575 | goto emulate_ri; |
| 1581 | break; | ||
| 1582 | } | 1576 | } |
| 1583 | } else { | 1577 | } else { |
| 1584 | printk("Emulate RI not supported @ %p: %#x\n", opc, inst); | 1578 | kvm_debug("Emulate RI not supported @ %p: %#x\n", opc, inst); |
| 1585 | er = EMULATE_FAIL; | 1579 | goto emulate_ri; |
| 1586 | } | 1580 | } |
| 1587 | 1581 | ||
| 1582 | return EMULATE_DONE; | ||
| 1583 | |||
| 1584 | emulate_ri: | ||
| 1588 | /* | 1585 | /* |
| 1589 | * Rollback PC only if emulation was unsuccessful | 1586 | * Rollback PC (if in branch delay slot then the PC already points to |
| 1587 | * branch target), and pass the RI exception to the guest OS. | ||
| 1590 | */ | 1588 | */ |
| 1591 | if (er == EMULATE_FAIL) { | 1589 | vcpu->arch.pc = curr_pc; |
| 1592 | vcpu->arch.pc = curr_pc; | 1590 | return kvm_mips_emulate_ri_exc(cause, opc, run, vcpu); |
| 1593 | } | ||
| 1594 | return er; | ||
| 1595 | } | 1591 | } |
| 1596 | 1592 | ||
| 1597 | enum emulation_result | 1593 | enum emulation_result |
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index c36cd35e03f3..68897fc65950 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h | |||
| @@ -19,10 +19,19 @@ | |||
| 19 | #include <linux/kvm.h> | 19 | #include <linux/kvm.h> |
| 20 | #include <asm/debug.h> | 20 | #include <asm/debug.h> |
| 21 | #include <asm/cpu.h> | 21 | #include <asm/cpu.h> |
| 22 | #include <asm/isc.h> | ||
| 22 | 23 | ||
| 23 | #define KVM_MAX_VCPUS 64 | 24 | #define KVM_MAX_VCPUS 64 |
| 24 | #define KVM_USER_MEM_SLOTS 32 | 25 | #define KVM_USER_MEM_SLOTS 32 |
| 25 | 26 | ||
| 27 | /* | ||
| 28 | * These seem to be used for allocating ->chip in the routing table, | ||
| 29 | * which we don't use. 4096 is an out-of-thin-air value. If we need | ||
| 30 | * to look at ->chip later on, we'll need to revisit this. | ||
| 31 | */ | ||
| 32 | #define KVM_NR_IRQCHIPS 1 | ||
| 33 | #define KVM_IRQCHIP_NUM_PINS 4096 | ||
| 34 | |||
| 26 | struct sca_entry { | 35 | struct sca_entry { |
| 27 | atomic_t scn; | 36 | atomic_t scn; |
| 28 | __u32 reserved; | 37 | __u32 reserved; |
| @@ -244,6 +253,27 @@ struct kvm_vm_stat { | |||
| 244 | struct kvm_arch_memory_slot { | 253 | struct kvm_arch_memory_slot { |
| 245 | }; | 254 | }; |
| 246 | 255 | ||
| 256 | struct s390_map_info { | ||
| 257 | struct list_head list; | ||
| 258 | __u64 guest_addr; | ||
| 259 | __u64 addr; | ||
| 260 | struct page *page; | ||
| 261 | }; | ||
| 262 | |||
| 263 | struct s390_io_adapter { | ||
| 264 | unsigned int id; | ||
| 265 | int isc; | ||
| 266 | bool maskable; | ||
| 267 | bool masked; | ||
| 268 | bool swap; | ||
| 269 | struct rw_semaphore maps_lock; | ||
| 270 | struct list_head maps; | ||
| 271 | atomic_t nr_maps; | ||
| 272 | }; | ||
| 273 | |||
| 274 | #define MAX_S390_IO_ADAPTERS ((MAX_ISC + 1) * 8) | ||
| 275 | #define MAX_S390_ADAPTER_MAPS 256 | ||
| 276 | |||
| 247 | struct kvm_arch{ | 277 | struct kvm_arch{ |
| 248 | struct sca_block *sca; | 278 | struct sca_block *sca; |
| 249 | debug_info_t *dbf; | 279 | debug_info_t *dbf; |
| @@ -251,6 +281,8 @@ struct kvm_arch{ | |||
| 251 | struct kvm_device *flic; | 281 | struct kvm_device *flic; |
| 252 | struct gmap *gmap; | 282 | struct gmap *gmap; |
| 253 | int css_support; | 283 | int css_support; |
| 284 | int use_irqchip; | ||
| 285 | struct s390_io_adapter *adapters[MAX_S390_IO_ADAPTERS]; | ||
| 254 | }; | 286 | }; |
| 255 | 287 | ||
| 256 | #define KVM_HVA_ERR_BAD (-1UL) | 288 | #define KVM_HVA_ERR_BAD (-1UL) |
diff --git a/arch/s390/include/uapi/asm/kvm.h b/arch/s390/include/uapi/asm/kvm.h index 2f0ade24f96a..c003c6a73b1e 100644 --- a/arch/s390/include/uapi/asm/kvm.h +++ b/arch/s390/include/uapi/asm/kvm.h | |||
| @@ -22,6 +22,8 @@ | |||
| 22 | #define KVM_DEV_FLIC_CLEAR_IRQS 3 | 22 | #define KVM_DEV_FLIC_CLEAR_IRQS 3 |
| 23 | #define KVM_DEV_FLIC_APF_ENABLE 4 | 23 | #define KVM_DEV_FLIC_APF_ENABLE 4 |
| 24 | #define KVM_DEV_FLIC_APF_DISABLE_WAIT 5 | 24 | #define KVM_DEV_FLIC_APF_DISABLE_WAIT 5 |
| 25 | #define KVM_DEV_FLIC_ADAPTER_REGISTER 6 | ||
| 26 | #define KVM_DEV_FLIC_ADAPTER_MODIFY 7 | ||
| 25 | /* | 27 | /* |
| 26 | * We can have up to 4*64k pending subchannels + 8 adapter interrupts, | 28 | * 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. | 29 | * as well as up to ASYNC_PF_PER_VCPU*KVM_MAX_VCPUS pfault done interrupts. |
| @@ -32,6 +34,26 @@ | |||
| 32 | #define KVM_S390_MAX_FLOAT_IRQS 266250 | 34 | #define KVM_S390_MAX_FLOAT_IRQS 266250 |
| 33 | #define KVM_S390_FLIC_MAX_BUFFER 0x2000000 | 35 | #define KVM_S390_FLIC_MAX_BUFFER 0x2000000 |
| 34 | 36 | ||
| 37 | struct kvm_s390_io_adapter { | ||
| 38 | __u32 id; | ||
| 39 | __u8 isc; | ||
| 40 | __u8 maskable; | ||
| 41 | __u8 swap; | ||
| 42 | __u8 pad; | ||
| 43 | }; | ||
| 44 | |||
| 45 | #define KVM_S390_IO_ADAPTER_MASK 1 | ||
| 46 | #define KVM_S390_IO_ADAPTER_MAP 2 | ||
| 47 | #define KVM_S390_IO_ADAPTER_UNMAP 3 | ||
| 48 | |||
| 49 | struct kvm_s390_io_adapter_req { | ||
| 50 | __u32 id; | ||
| 51 | __u8 type; | ||
| 52 | __u8 mask; | ||
| 53 | __u16 pad0; | ||
| 54 | __u64 addr; | ||
| 55 | }; | ||
| 56 | |||
| 35 | /* for KVM_GET_REGS and KVM_SET_REGS */ | 57 | /* for KVM_GET_REGS and KVM_SET_REGS */ |
| 36 | struct kvm_regs { | 58 | struct kvm_regs { |
| 37 | /* general purpose regs for s390 */ | 59 | /* general purpose regs for s390 */ |
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig index c8bacbcd2e5b..10d529ac9821 100644 --- a/arch/s390/kvm/Kconfig +++ b/arch/s390/kvm/Kconfig | |||
| @@ -25,6 +25,8 @@ config KVM | |||
| 25 | select HAVE_KVM_EVENTFD | 25 | select HAVE_KVM_EVENTFD |
| 26 | select KVM_ASYNC_PF | 26 | select KVM_ASYNC_PF |
| 27 | select KVM_ASYNC_PF_SYNC | 27 | select KVM_ASYNC_PF_SYNC |
| 28 | select HAVE_KVM_IRQCHIP | ||
| 29 | select HAVE_KVM_IRQ_ROUTING | ||
| 28 | ---help--- | 30 | ---help--- |
| 29 | Support hosting paravirtualized guest machines using the SIE | 31 | Support hosting paravirtualized guest machines using the SIE |
| 30 | virtualization capability on the mainframe. This should work | 32 | virtualization capability on the mainframe. This should work |
diff --git a/arch/s390/kvm/Makefile b/arch/s390/kvm/Makefile index a47d2c355f68..d3adb37e93a4 100644 --- a/arch/s390/kvm/Makefile +++ b/arch/s390/kvm/Makefile | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | # as published by the Free Software Foundation. | 7 | # as published by the Free Software Foundation. |
| 8 | 8 | ||
| 9 | KVM := ../../../virt/kvm | 9 | KVM := ../../../virt/kvm |
| 10 | common-objs = $(KVM)/kvm_main.o $(KVM)/eventfd.o $(KVM)/async_pf.o | 10 | common-objs = $(KVM)/kvm_main.o $(KVM)/eventfd.o $(KVM)/async_pf.o $(KVM)/irqchip.o |
| 11 | 11 | ||
| 12 | ccflags-y := -Ivirt/kvm -Iarch/s390/kvm | 12 | ccflags-y := -Ivirt/kvm -Iarch/s390/kvm |
| 13 | 13 | ||
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 05bffd74961f..200a8f9390b6 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * handling kvm guest interrupts | 2 | * handling kvm guest interrupts |
| 3 | * | 3 | * |
| 4 | * Copyright IBM Corp. 2008 | 4 | * Copyright IBM Corp. 2008,2014 |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License (version 2 only) | 7 | * it under the terms of the GNU General Public License (version 2 only) |
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
| 14 | #include <linux/kvm_host.h> | 14 | #include <linux/kvm_host.h> |
| 15 | #include <linux/hrtimer.h> | 15 | #include <linux/hrtimer.h> |
| 16 | #include <linux/mmu_context.h> | ||
| 16 | #include <linux/signal.h> | 17 | #include <linux/signal.h> |
| 17 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
| 18 | #include <asm/asm-offsets.h> | 19 | #include <asm/asm-offsets.h> |
| @@ -1068,6 +1069,171 @@ static int enqueue_floating_irq(struct kvm_device *dev, | |||
| 1068 | return r; | 1069 | return r; |
| 1069 | } | 1070 | } |
| 1070 | 1071 | ||
| 1072 | static struct s390_io_adapter *get_io_adapter(struct kvm *kvm, unsigned int id) | ||
| 1073 | { | ||
| 1074 | if (id >= MAX_S390_IO_ADAPTERS) | ||
| 1075 | return NULL; | ||
| 1076 | return kvm->arch.adapters[id]; | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | static int register_io_adapter(struct kvm_device *dev, | ||
| 1080 | struct kvm_device_attr *attr) | ||
| 1081 | { | ||
| 1082 | struct s390_io_adapter *adapter; | ||
| 1083 | struct kvm_s390_io_adapter adapter_info; | ||
| 1084 | |||
| 1085 | if (copy_from_user(&adapter_info, | ||
| 1086 | (void __user *)attr->addr, sizeof(adapter_info))) | ||
| 1087 | return -EFAULT; | ||
| 1088 | |||
| 1089 | if ((adapter_info.id >= MAX_S390_IO_ADAPTERS) || | ||
| 1090 | (dev->kvm->arch.adapters[adapter_info.id] != NULL)) | ||
| 1091 | return -EINVAL; | ||
| 1092 | |||
| 1093 | adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); | ||
| 1094 | if (!adapter) | ||
| 1095 | return -ENOMEM; | ||
| 1096 | |||
| 1097 | INIT_LIST_HEAD(&adapter->maps); | ||
| 1098 | init_rwsem(&adapter->maps_lock); | ||
| 1099 | atomic_set(&adapter->nr_maps, 0); | ||
| 1100 | adapter->id = adapter_info.id; | ||
| 1101 | adapter->isc = adapter_info.isc; | ||
| 1102 | adapter->maskable = adapter_info.maskable; | ||
| 1103 | adapter->masked = false; | ||
| 1104 | adapter->swap = adapter_info.swap; | ||
| 1105 | dev->kvm->arch.adapters[adapter->id] = adapter; | ||
| 1106 | |||
| 1107 | return 0; | ||
| 1108 | } | ||
| 1109 | |||
| 1110 | int kvm_s390_mask_adapter(struct kvm *kvm, unsigned int id, bool masked) | ||
| 1111 | { | ||
| 1112 | int ret; | ||
| 1113 | struct s390_io_adapter *adapter = get_io_adapter(kvm, id); | ||
| 1114 | |||
| 1115 | if (!adapter || !adapter->maskable) | ||
| 1116 | return -EINVAL; | ||
| 1117 | ret = adapter->masked; | ||
| 1118 | adapter->masked = masked; | ||
| 1119 | return ret; | ||
| 1120 | } | ||
| 1121 | |||
| 1122 | static int kvm_s390_adapter_map(struct kvm *kvm, unsigned int id, __u64 addr) | ||
| 1123 | { | ||
| 1124 | struct s390_io_adapter *adapter = get_io_adapter(kvm, id); | ||
| 1125 | struct s390_map_info *map; | ||
| 1126 | int ret; | ||
| 1127 | |||
| 1128 | if (!adapter || !addr) | ||
| 1129 | return -EINVAL; | ||
| 1130 | |||
| 1131 | map = kzalloc(sizeof(*map), GFP_KERNEL); | ||
| 1132 | if (!map) { | ||
| 1133 | ret = -ENOMEM; | ||
| 1134 | goto out; | ||
| 1135 | } | ||
| 1136 | INIT_LIST_HEAD(&map->list); | ||
| 1137 | map->guest_addr = addr; | ||
| 1138 | map->addr = gmap_translate(addr, kvm->arch.gmap); | ||
| 1139 | if (map->addr == -EFAULT) { | ||
| 1140 | ret = -EFAULT; | ||
| 1141 | goto out; | ||
| 1142 | } | ||
| 1143 | ret = get_user_pages_fast(map->addr, 1, 1, &map->page); | ||
| 1144 | if (ret < 0) | ||
| 1145 | goto out; | ||
| 1146 | BUG_ON(ret != 1); | ||
| 1147 | down_write(&adapter->maps_lock); | ||
| 1148 | if (atomic_inc_return(&adapter->nr_maps) < MAX_S390_ADAPTER_MAPS) { | ||
| 1149 | list_add_tail(&map->list, &adapter->maps); | ||
| 1150 | ret = 0; | ||
| 1151 | } else { | ||
| 1152 | put_page(map->page); | ||
| 1153 | ret = -EINVAL; | ||
| 1154 | } | ||
| 1155 | up_write(&adapter->maps_lock); | ||
| 1156 | out: | ||
| 1157 | if (ret) | ||
| 1158 | kfree(map); | ||
| 1159 | return ret; | ||
| 1160 | } | ||
| 1161 | |||
| 1162 | static int kvm_s390_adapter_unmap(struct kvm *kvm, unsigned int id, __u64 addr) | ||
| 1163 | { | ||
| 1164 | struct s390_io_adapter *adapter = get_io_adapter(kvm, id); | ||
| 1165 | struct s390_map_info *map, *tmp; | ||
| 1166 | int found = 0; | ||
| 1167 | |||
| 1168 | if (!adapter || !addr) | ||
| 1169 | return -EINVAL; | ||
| 1170 | |||
| 1171 | down_write(&adapter->maps_lock); | ||
| 1172 | list_for_each_entry_safe(map, tmp, &adapter->maps, list) { | ||
| 1173 | if (map->guest_addr == addr) { | ||
| 1174 | found = 1; | ||
| 1175 | atomic_dec(&adapter->nr_maps); | ||
| 1176 | list_del(&map->list); | ||
| 1177 | put_page(map->page); | ||
| 1178 | kfree(map); | ||
| 1179 | break; | ||
| 1180 | } | ||
| 1181 | } | ||
| 1182 | up_write(&adapter->maps_lock); | ||
| 1183 | |||
| 1184 | return found ? 0 : -EINVAL; | ||
| 1185 | } | ||
| 1186 | |||
| 1187 | void kvm_s390_destroy_adapters(struct kvm *kvm) | ||
| 1188 | { | ||
| 1189 | int i; | ||
| 1190 | struct s390_map_info *map, *tmp; | ||
| 1191 | |||
| 1192 | for (i = 0; i < MAX_S390_IO_ADAPTERS; i++) { | ||
| 1193 | if (!kvm->arch.adapters[i]) | ||
| 1194 | continue; | ||
| 1195 | list_for_each_entry_safe(map, tmp, | ||
| 1196 | &kvm->arch.adapters[i]->maps, list) { | ||
| 1197 | list_del(&map->list); | ||
| 1198 | put_page(map->page); | ||
| 1199 | kfree(map); | ||
| 1200 | } | ||
| 1201 | kfree(kvm->arch.adapters[i]); | ||
| 1202 | } | ||
| 1203 | } | ||
| 1204 | |||
| 1205 | static int modify_io_adapter(struct kvm_device *dev, | ||
| 1206 | struct kvm_device_attr *attr) | ||
| 1207 | { | ||
| 1208 | struct kvm_s390_io_adapter_req req; | ||
| 1209 | struct s390_io_adapter *adapter; | ||
| 1210 | int ret; | ||
| 1211 | |||
| 1212 | if (copy_from_user(&req, (void __user *)attr->addr, sizeof(req))) | ||
| 1213 | return -EFAULT; | ||
| 1214 | |||
| 1215 | adapter = get_io_adapter(dev->kvm, req.id); | ||
| 1216 | if (!adapter) | ||
| 1217 | return -EINVAL; | ||
| 1218 | switch (req.type) { | ||
| 1219 | case KVM_S390_IO_ADAPTER_MASK: | ||
| 1220 | ret = kvm_s390_mask_adapter(dev->kvm, req.id, req.mask); | ||
| 1221 | if (ret > 0) | ||
| 1222 | ret = 0; | ||
| 1223 | break; | ||
| 1224 | case KVM_S390_IO_ADAPTER_MAP: | ||
| 1225 | ret = kvm_s390_adapter_map(dev->kvm, req.id, req.addr); | ||
| 1226 | break; | ||
| 1227 | case KVM_S390_IO_ADAPTER_UNMAP: | ||
| 1228 | ret = kvm_s390_adapter_unmap(dev->kvm, req.id, req.addr); | ||
| 1229 | break; | ||
| 1230 | default: | ||
| 1231 | ret = -EINVAL; | ||
| 1232 | } | ||
| 1233 | |||
| 1234 | return ret; | ||
| 1235 | } | ||
| 1236 | |||
| 1071 | static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) | 1237 | static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) |
| 1072 | { | 1238 | { |
| 1073 | int r = 0; | 1239 | int r = 0; |
| @@ -1096,6 +1262,12 @@ static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) | |||
| 1096 | kvm_for_each_vcpu(i, vcpu, dev->kvm) | 1262 | kvm_for_each_vcpu(i, vcpu, dev->kvm) |
| 1097 | kvm_clear_async_pf_completion_queue(vcpu); | 1263 | kvm_clear_async_pf_completion_queue(vcpu); |
| 1098 | break; | 1264 | break; |
| 1265 | case KVM_DEV_FLIC_ADAPTER_REGISTER: | ||
| 1266 | r = register_io_adapter(dev, attr); | ||
| 1267 | break; | ||
| 1268 | case KVM_DEV_FLIC_ADAPTER_MODIFY: | ||
| 1269 | r = modify_io_adapter(dev, attr); | ||
| 1270 | break; | ||
| 1099 | default: | 1271 | default: |
| 1100 | r = -EINVAL; | 1272 | r = -EINVAL; |
| 1101 | } | 1273 | } |
| @@ -1127,3 +1299,123 @@ struct kvm_device_ops kvm_flic_ops = { | |||
| 1127 | .create = flic_create, | 1299 | .create = flic_create, |
| 1128 | .destroy = flic_destroy, | 1300 | .destroy = flic_destroy, |
| 1129 | }; | 1301 | }; |
| 1302 | |||
| 1303 | static unsigned long get_ind_bit(__u64 addr, unsigned long bit_nr, bool swap) | ||
| 1304 | { | ||
| 1305 | unsigned long bit; | ||
| 1306 | |||
| 1307 | bit = bit_nr + (addr % PAGE_SIZE) * 8; | ||
| 1308 | |||
| 1309 | return swap ? (bit ^ (BITS_PER_LONG - 1)) : bit; | ||
| 1310 | } | ||
| 1311 | |||
| 1312 | static struct s390_map_info *get_map_info(struct s390_io_adapter *adapter, | ||
| 1313 | u64 addr) | ||
| 1314 | { | ||
| 1315 | struct s390_map_info *map; | ||
| 1316 | |||
| 1317 | if (!adapter) | ||
| 1318 | return NULL; | ||
| 1319 | |||
| 1320 | list_for_each_entry(map, &adapter->maps, list) { | ||
| 1321 | if (map->guest_addr == addr) | ||
| 1322 | return map; | ||
| 1323 | } | ||
| 1324 | return NULL; | ||
| 1325 | } | ||
| 1326 | |||
| 1327 | static int adapter_indicators_set(struct kvm *kvm, | ||
| 1328 | struct s390_io_adapter *adapter, | ||
| 1329 | struct kvm_s390_adapter_int *adapter_int) | ||
| 1330 | { | ||
| 1331 | unsigned long bit; | ||
| 1332 | int summary_set, idx; | ||
| 1333 | struct s390_map_info *info; | ||
| 1334 | void *map; | ||
| 1335 | |||
| 1336 | info = get_map_info(adapter, adapter_int->ind_addr); | ||
| 1337 | if (!info) | ||
| 1338 | return -1; | ||
| 1339 | map = page_address(info->page); | ||
| 1340 | bit = get_ind_bit(info->addr, adapter_int->ind_offset, adapter->swap); | ||
| 1341 | set_bit(bit, map); | ||
| 1342 | idx = srcu_read_lock(&kvm->srcu); | ||
| 1343 | mark_page_dirty(kvm, info->guest_addr >> PAGE_SHIFT); | ||
| 1344 | set_page_dirty_lock(info->page); | ||
| 1345 | info = get_map_info(adapter, adapter_int->summary_addr); | ||
| 1346 | if (!info) { | ||
| 1347 | srcu_read_unlock(&kvm->srcu, idx); | ||
| 1348 | return -1; | ||
| 1349 | } | ||
| 1350 | map = page_address(info->page); | ||
| 1351 | bit = get_ind_bit(info->addr, adapter_int->summary_offset, | ||
| 1352 | adapter->swap); | ||
| 1353 | summary_set = test_and_set_bit(bit, map); | ||
| 1354 | mark_page_dirty(kvm, info->guest_addr >> PAGE_SHIFT); | ||
| 1355 | set_page_dirty_lock(info->page); | ||
| 1356 | srcu_read_unlock(&kvm->srcu, idx); | ||
| 1357 | return summary_set ? 0 : 1; | ||
| 1358 | } | ||
| 1359 | |||
| 1360 | /* | ||
| 1361 | * < 0 - not injected due to error | ||
| 1362 | * = 0 - coalesced, summary indicator already active | ||
| 1363 | * > 0 - injected interrupt | ||
| 1364 | */ | ||
| 1365 | static int set_adapter_int(struct kvm_kernel_irq_routing_entry *e, | ||
| 1366 | struct kvm *kvm, int irq_source_id, int level, | ||
| 1367 | bool line_status) | ||
| 1368 | { | ||
| 1369 | int ret; | ||
| 1370 | struct s390_io_adapter *adapter; | ||
| 1371 | |||
| 1372 | /* We're only interested in the 0->1 transition. */ | ||
| 1373 | if (!level) | ||
| 1374 | return 0; | ||
| 1375 | adapter = get_io_adapter(kvm, e->adapter.adapter_id); | ||
| 1376 | if (!adapter) | ||
| 1377 | return -1; | ||
| 1378 | down_read(&adapter->maps_lock); | ||
| 1379 | ret = adapter_indicators_set(kvm, adapter, &e->adapter); | ||
| 1380 | up_read(&adapter->maps_lock); | ||
| 1381 | if ((ret > 0) && !adapter->masked) { | ||
| 1382 | struct kvm_s390_interrupt s390int = { | ||
| 1383 | .type = KVM_S390_INT_IO(1, 0, 0, 0), | ||
| 1384 | .parm = 0, | ||
| 1385 | .parm64 = (adapter->isc << 27) | 0x80000000, | ||
| 1386 | }; | ||
| 1387 | ret = kvm_s390_inject_vm(kvm, &s390int); | ||
| 1388 | if (ret == 0) | ||
| 1389 | ret = 1; | ||
| 1390 | } | ||
| 1391 | return ret; | ||
| 1392 | } | ||
| 1393 | |||
| 1394 | int kvm_set_routing_entry(struct kvm_irq_routing_table *rt, | ||
| 1395 | struct kvm_kernel_irq_routing_entry *e, | ||
| 1396 | const struct kvm_irq_routing_entry *ue) | ||
| 1397 | { | ||
| 1398 | int ret; | ||
| 1399 | |||
| 1400 | switch (ue->type) { | ||
| 1401 | case KVM_IRQ_ROUTING_S390_ADAPTER: | ||
| 1402 | e->set = set_adapter_int; | ||
| 1403 | e->adapter.summary_addr = ue->u.adapter.summary_addr; | ||
| 1404 | e->adapter.ind_addr = ue->u.adapter.ind_addr; | ||
| 1405 | e->adapter.summary_offset = ue->u.adapter.summary_offset; | ||
| 1406 | e->adapter.ind_offset = ue->u.adapter.ind_offset; | ||
| 1407 | e->adapter.adapter_id = ue->u.adapter.adapter_id; | ||
| 1408 | ret = 0; | ||
| 1409 | break; | ||
| 1410 | default: | ||
| 1411 | ret = -EINVAL; | ||
| 1412 | } | ||
| 1413 | |||
| 1414 | return ret; | ||
| 1415 | } | ||
| 1416 | |||
| 1417 | int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, struct kvm *kvm, | ||
| 1418 | int irq_source_id, int level, bool line_status) | ||
| 1419 | { | ||
| 1420 | return -EINVAL; | ||
| 1421 | } | ||
diff --git a/arch/s390/kvm/irq.h b/arch/s390/kvm/irq.h new file mode 100644 index 000000000000..d98e4159643d --- /dev/null +++ b/arch/s390/kvm/irq.h | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | /* | ||
| 2 | * s390 irqchip routines | ||
| 3 | * | ||
| 4 | * Copyright IBM Corp. 2014 | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License (version 2 only) | ||
| 8 | * as published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com> | ||
| 11 | */ | ||
| 12 | #ifndef __KVM_IRQ_H | ||
| 13 | #define __KVM_IRQ_H | ||
| 14 | |||
| 15 | #include <linux/kvm_host.h> | ||
| 16 | |||
| 17 | static inline int irqchip_in_kernel(struct kvm *kvm) | ||
| 18 | { | ||
| 19 | return 1; | ||
| 20 | } | ||
| 21 | |||
| 22 | #endif | ||
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 83b79447de55..6e1b990e427f 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
| @@ -159,6 +159,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
| 159 | case KVM_CAP_S390_CSS_SUPPORT: | 159 | case KVM_CAP_S390_CSS_SUPPORT: |
| 160 | case KVM_CAP_IOEVENTFD: | 160 | case KVM_CAP_IOEVENTFD: |
| 161 | case KVM_CAP_DEVICE_CTRL: | 161 | case KVM_CAP_DEVICE_CTRL: |
| 162 | case KVM_CAP_ENABLE_CAP_VM: | ||
| 162 | r = 1; | 163 | r = 1; |
| 163 | break; | 164 | break; |
| 164 | case KVM_CAP_NR_VCPUS: | 165 | case KVM_CAP_NR_VCPUS: |
| @@ -187,6 +188,25 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, | |||
| 187 | return 0; | 188 | return 0; |
| 188 | } | 189 | } |
| 189 | 190 | ||
| 191 | static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap) | ||
| 192 | { | ||
| 193 | int r; | ||
| 194 | |||
| 195 | if (cap->flags) | ||
| 196 | return -EINVAL; | ||
| 197 | |||
| 198 | switch (cap->cap) { | ||
| 199 | case KVM_CAP_S390_IRQCHIP: | ||
| 200 | kvm->arch.use_irqchip = 1; | ||
| 201 | r = 0; | ||
| 202 | break; | ||
| 203 | default: | ||
| 204 | r = -EINVAL; | ||
| 205 | break; | ||
| 206 | } | ||
| 207 | return r; | ||
| 208 | } | ||
| 209 | |||
| 190 | long kvm_arch_vm_ioctl(struct file *filp, | 210 | long kvm_arch_vm_ioctl(struct file *filp, |
| 191 | unsigned int ioctl, unsigned long arg) | 211 | unsigned int ioctl, unsigned long arg) |
| 192 | { | 212 | { |
| @@ -204,6 +224,26 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
| 204 | r = kvm_s390_inject_vm(kvm, &s390int); | 224 | r = kvm_s390_inject_vm(kvm, &s390int); |
| 205 | break; | 225 | break; |
| 206 | } | 226 | } |
| 227 | case KVM_ENABLE_CAP: { | ||
| 228 | struct kvm_enable_cap cap; | ||
| 229 | r = -EFAULT; | ||
| 230 | if (copy_from_user(&cap, argp, sizeof(cap))) | ||
| 231 | break; | ||
| 232 | r = kvm_vm_ioctl_enable_cap(kvm, &cap); | ||
| 233 | break; | ||
| 234 | } | ||
| 235 | case KVM_CREATE_IRQCHIP: { | ||
| 236 | struct kvm_irq_routing_entry routing; | ||
| 237 | |||
| 238 | r = -EINVAL; | ||
| 239 | if (kvm->arch.use_irqchip) { | ||
| 240 | /* Set up dummy routing. */ | ||
| 241 | memset(&routing, 0, sizeof(routing)); | ||
| 242 | kvm_set_irq_routing(kvm, &routing, 0, 0); | ||
| 243 | r = 0; | ||
| 244 | } | ||
| 245 | break; | ||
| 246 | } | ||
| 207 | default: | 247 | default: |
| 208 | r = -ENOTTY; | 248 | r = -ENOTTY; |
| 209 | } | 249 | } |
| @@ -265,6 +305,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | |||
| 265 | } | 305 | } |
| 266 | 306 | ||
| 267 | kvm->arch.css_support = 0; | 307 | kvm->arch.css_support = 0; |
| 308 | kvm->arch.use_irqchip = 0; | ||
| 268 | 309 | ||
| 269 | return 0; | 310 | return 0; |
| 270 | out_nogmap: | 311 | out_nogmap: |
| @@ -324,6 +365,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm) | |||
| 324 | debug_unregister(kvm->arch.dbf); | 365 | debug_unregister(kvm->arch.dbf); |
| 325 | if (!kvm_is_ucontrol(kvm)) | 366 | if (!kvm_is_ucontrol(kvm)) |
| 326 | gmap_free(kvm->arch.gmap); | 367 | gmap_free(kvm->arch.gmap); |
| 368 | kvm_s390_destroy_adapters(kvm); | ||
| 327 | } | 369 | } |
| 328 | 370 | ||
| 329 | /* Section: vcpu related */ | 371 | /* Section: vcpu related */ |
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index 6311170843b6..660e79f8f8e8 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h | |||
| @@ -137,6 +137,7 @@ int __must_check kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, | |||
| 137 | int __must_check kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code); | 137 | int __must_check kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code); |
| 138 | struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, | 138 | struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, |
| 139 | u64 cr6, u64 schid); | 139 | u64 cr6, u64 schid); |
| 140 | int kvm_s390_mask_adapter(struct kvm *kvm, unsigned int id, bool masked); | ||
| 140 | 141 | ||
| 141 | /* implemented in priv.c */ | 142 | /* implemented in priv.c */ |
| 142 | int kvm_s390_handle_b2(struct kvm_vcpu *vcpu); | 143 | int kvm_s390_handle_b2(struct kvm_vcpu *vcpu); |
| @@ -163,5 +164,6 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu); | |||
| 163 | /* implemented in interrupt.c */ | 164 | /* implemented in interrupt.c */ |
| 164 | int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu); | 165 | int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu); |
| 165 | int psw_extint_disabled(struct kvm_vcpu *vcpu); | 166 | int psw_extint_disabled(struct kvm_vcpu *vcpu); |
| 167 | void kvm_s390_destroy_adapters(struct kvm *kvm); | ||
| 166 | 168 | ||
| 167 | #endif | 169 | #endif |
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index ddc8a7e165df..64fae65730f3 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c | |||
| @@ -43,6 +43,16 @@ static u32 xstate_required_size(u64 xstate_bv) | |||
| 43 | return ret; | 43 | return ret; |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | u64 kvm_supported_xcr0(void) | ||
| 47 | { | ||
| 48 | u64 xcr0 = KVM_SUPPORTED_XCR0 & host_xcr0; | ||
| 49 | |||
| 50 | if (!kvm_x86_ops->mpx_supported()) | ||
| 51 | xcr0 &= ~(XSTATE_BNDREGS | XSTATE_BNDCSR); | ||
| 52 | |||
| 53 | return xcr0; | ||
| 54 | } | ||
| 55 | |||
| 46 | void kvm_update_cpuid(struct kvm_vcpu *vcpu) | 56 | void kvm_update_cpuid(struct kvm_vcpu *vcpu) |
| 47 | { | 57 | { |
| 48 | struct kvm_cpuid_entry2 *best; | 58 | struct kvm_cpuid_entry2 *best; |
| @@ -73,7 +83,7 @@ void kvm_update_cpuid(struct kvm_vcpu *vcpu) | |||
| 73 | } else { | 83 | } else { |
| 74 | vcpu->arch.guest_supported_xcr0 = | 84 | vcpu->arch.guest_supported_xcr0 = |
| 75 | (best->eax | ((u64)best->edx << 32)) & | 85 | (best->eax | ((u64)best->edx << 32)) & |
| 76 | host_xcr0 & KVM_SUPPORTED_XCR0; | 86 | kvm_supported_xcr0(); |
| 77 | vcpu->arch.guest_xstate_size = best->ebx = | 87 | vcpu->arch.guest_xstate_size = best->ebx = |
| 78 | xstate_required_size(vcpu->arch.xcr0); | 88 | xstate_required_size(vcpu->arch.xcr0); |
| 79 | } | 89 | } |
| @@ -210,13 +220,6 @@ static void do_cpuid_1_ent(struct kvm_cpuid_entry2 *entry, u32 function, | |||
| 210 | entry->flags = 0; | 220 | entry->flags = 0; |
| 211 | } | 221 | } |
| 212 | 222 | ||
| 213 | static bool supported_xcr0_bit(unsigned bit) | ||
| 214 | { | ||
| 215 | u64 mask = ((u64)1 << bit); | ||
| 216 | |||
| 217 | return mask & KVM_SUPPORTED_XCR0 & host_xcr0; | ||
| 218 | } | ||
| 219 | |||
| 220 | #define F(x) bit(X86_FEATURE_##x) | 223 | #define F(x) bit(X86_FEATURE_##x) |
| 221 | 224 | ||
| 222 | static int __do_cpuid_ent_emulated(struct kvm_cpuid_entry2 *entry, | 225 | static int __do_cpuid_ent_emulated(struct kvm_cpuid_entry2 *entry, |
| @@ -256,8 +259,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, | |||
| 256 | #endif | 259 | #endif |
| 257 | unsigned f_rdtscp = kvm_x86_ops->rdtscp_supported() ? F(RDTSCP) : 0; | 260 | unsigned f_rdtscp = kvm_x86_ops->rdtscp_supported() ? F(RDTSCP) : 0; |
| 258 | unsigned f_invpcid = kvm_x86_ops->invpcid_supported() ? F(INVPCID) : 0; | 261 | unsigned f_invpcid = kvm_x86_ops->invpcid_supported() ? F(INVPCID) : 0; |
| 259 | unsigned f_mpx = kvm_x86_ops->mpx_supported ? | 262 | unsigned f_mpx = kvm_x86_ops->mpx_supported() ? F(MPX) : 0; |
| 260 | (kvm_x86_ops->mpx_supported() ? F(MPX) : 0) : 0; | ||
| 261 | 263 | ||
| 262 | /* cpuid 1.edx */ | 264 | /* cpuid 1.edx */ |
| 263 | const u32 kvm_supported_word0_x86_features = | 265 | const u32 kvm_supported_word0_x86_features = |
| @@ -439,16 +441,18 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, | |||
| 439 | } | 441 | } |
| 440 | case 0xd: { | 442 | case 0xd: { |
| 441 | int idx, i; | 443 | int idx, i; |
| 444 | u64 supported = kvm_supported_xcr0(); | ||
| 442 | 445 | ||
| 443 | entry->eax &= host_xcr0 & KVM_SUPPORTED_XCR0; | 446 | entry->eax &= supported; |
| 444 | entry->edx &= (host_xcr0 & KVM_SUPPORTED_XCR0) >> 32; | 447 | entry->edx &= supported >> 32; |
| 445 | entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX; | 448 | entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX; |
| 446 | for (idx = 1, i = 1; idx < 64; ++idx) { | 449 | for (idx = 1, i = 1; idx < 64; ++idx) { |
| 450 | u64 mask = ((u64)1 << idx); | ||
| 447 | if (*nent >= maxnent) | 451 | if (*nent >= maxnent) |
| 448 | goto out; | 452 | goto out; |
| 449 | 453 | ||
| 450 | do_cpuid_1_ent(&entry[i], function, idx); | 454 | do_cpuid_1_ent(&entry[i], function, idx); |
| 451 | if (entry[i].eax == 0 || !supported_xcr0_bit(idx)) | 455 | if (entry[i].eax == 0 || !(supported & mask)) |
| 452 | continue; | 456 | continue; |
| 453 | entry[i].flags |= | 457 | entry[i].flags |= |
| 454 | KVM_CPUID_FLAG_SIGNIFCANT_INDEX; | 458 | KVM_CPUID_FLAG_SIGNIFCANT_INDEX; |
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index a449c3d76cba..2136cb6ab132 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
| @@ -4089,6 +4089,11 @@ static bool svm_invpcid_supported(void) | |||
| 4089 | return false; | 4089 | return false; |
| 4090 | } | 4090 | } |
| 4091 | 4091 | ||
| 4092 | static bool svm_mpx_supported(void) | ||
| 4093 | { | ||
| 4094 | return false; | ||
| 4095 | } | ||
| 4096 | |||
| 4092 | static bool svm_has_wbinvd_exit(void) | 4097 | static bool svm_has_wbinvd_exit(void) |
| 4093 | { | 4098 | { |
| 4094 | return true; | 4099 | return true; |
| @@ -4371,6 +4376,7 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
| 4371 | 4376 | ||
| 4372 | .rdtscp_supported = svm_rdtscp_supported, | 4377 | .rdtscp_supported = svm_rdtscp_supported, |
| 4373 | .invpcid_supported = svm_invpcid_supported, | 4378 | .invpcid_supported = svm_invpcid_supported, |
| 4379 | .mpx_supported = svm_mpx_supported, | ||
| 4374 | 4380 | ||
| 4375 | .set_supported_cpuid = svm_set_supported_cpuid, | 4381 | .set_supported_cpuid = svm_set_supported_cpuid, |
| 4376 | 4382 | ||
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index f4e5aeda5edf..1320e0f8e611 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
| @@ -206,6 +206,7 @@ struct __packed vmcs12 { | |||
| 206 | u64 guest_pdptr1; | 206 | u64 guest_pdptr1; |
| 207 | u64 guest_pdptr2; | 207 | u64 guest_pdptr2; |
| 208 | u64 guest_pdptr3; | 208 | u64 guest_pdptr3; |
| 209 | u64 guest_bndcfgs; | ||
| 209 | u64 host_ia32_pat; | 210 | u64 host_ia32_pat; |
| 210 | u64 host_ia32_efer; | 211 | u64 host_ia32_efer; |
| 211 | u64 host_ia32_perf_global_ctrl; | 212 | u64 host_ia32_perf_global_ctrl; |
| @@ -541,6 +542,7 @@ static const unsigned long shadow_read_write_fields[] = { | |||
| 541 | GUEST_CS_LIMIT, | 542 | GUEST_CS_LIMIT, |
| 542 | GUEST_CS_BASE, | 543 | GUEST_CS_BASE, |
| 543 | GUEST_ES_BASE, | 544 | GUEST_ES_BASE, |
| 545 | GUEST_BNDCFGS, | ||
| 544 | CR0_GUEST_HOST_MASK, | 546 | CR0_GUEST_HOST_MASK, |
| 545 | CR0_READ_SHADOW, | 547 | CR0_READ_SHADOW, |
| 546 | CR4_READ_SHADOW, | 548 | CR4_READ_SHADOW, |
| @@ -596,6 +598,7 @@ static const unsigned short vmcs_field_to_offset_table[] = { | |||
| 596 | FIELD64(GUEST_PDPTR1, guest_pdptr1), | 598 | FIELD64(GUEST_PDPTR1, guest_pdptr1), |
| 597 | FIELD64(GUEST_PDPTR2, guest_pdptr2), | 599 | FIELD64(GUEST_PDPTR2, guest_pdptr2), |
| 598 | FIELD64(GUEST_PDPTR3, guest_pdptr3), | 600 | FIELD64(GUEST_PDPTR3, guest_pdptr3), |
| 601 | FIELD64(GUEST_BNDCFGS, guest_bndcfgs), | ||
| 599 | FIELD64(HOST_IA32_PAT, host_ia32_pat), | 602 | FIELD64(HOST_IA32_PAT, host_ia32_pat), |
| 600 | FIELD64(HOST_IA32_EFER, host_ia32_efer), | 603 | FIELD64(HOST_IA32_EFER, host_ia32_efer), |
| 601 | FIELD64(HOST_IA32_PERF_GLOBAL_CTRL, host_ia32_perf_global_ctrl), | 604 | FIELD64(HOST_IA32_PERF_GLOBAL_CTRL, host_ia32_perf_global_ctrl), |
| @@ -726,6 +729,7 @@ static unsigned long nested_ept_get_cr3(struct kvm_vcpu *vcpu); | |||
| 726 | static u64 construct_eptp(unsigned long root_hpa); | 729 | static u64 construct_eptp(unsigned long root_hpa); |
| 727 | static void kvm_cpu_vmxon(u64 addr); | 730 | static void kvm_cpu_vmxon(u64 addr); |
| 728 | static void kvm_cpu_vmxoff(void); | 731 | static void kvm_cpu_vmxoff(void); |
| 732 | static bool vmx_mpx_supported(void); | ||
| 729 | static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr); | 733 | static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr); |
| 730 | static void vmx_set_segment(struct kvm_vcpu *vcpu, | 734 | static void vmx_set_segment(struct kvm_vcpu *vcpu, |
| 731 | struct kvm_segment *var, int seg); | 735 | struct kvm_segment *var, int seg); |
| @@ -736,6 +740,7 @@ static u32 vmx_segment_access_rights(struct kvm_segment *var); | |||
| 736 | static void vmx_sync_pir_to_irr_dummy(struct kvm_vcpu *vcpu); | 740 | static void vmx_sync_pir_to_irr_dummy(struct kvm_vcpu *vcpu); |
| 737 | static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx); | 741 | static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx); |
| 738 | static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx); | 742 | static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx); |
| 743 | static bool vmx_mpx_supported(void); | ||
| 739 | 744 | ||
| 740 | static DEFINE_PER_CPU(struct vmcs *, vmxarea); | 745 | static DEFINE_PER_CPU(struct vmcs *, vmxarea); |
| 741 | static DEFINE_PER_CPU(struct vmcs *, current_vmcs); | 746 | static DEFINE_PER_CPU(struct vmcs *, current_vmcs); |
| @@ -2287,6 +2292,8 @@ static __init void nested_vmx_setup_ctls_msrs(void) | |||
| 2287 | nested_vmx_exit_ctls_high |= VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR | | 2292 | nested_vmx_exit_ctls_high |= VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR | |
| 2288 | VM_EXIT_LOAD_IA32_EFER | VM_EXIT_SAVE_IA32_EFER | | 2293 | VM_EXIT_LOAD_IA32_EFER | VM_EXIT_SAVE_IA32_EFER | |
| 2289 | VM_EXIT_SAVE_VMX_PREEMPTION_TIMER; | 2294 | VM_EXIT_SAVE_VMX_PREEMPTION_TIMER; |
| 2295 | if (vmx_mpx_supported()) | ||
| 2296 | nested_vmx_exit_ctls_high |= VM_EXIT_CLEAR_BNDCFGS; | ||
| 2290 | 2297 | ||
| 2291 | /* entry controls */ | 2298 | /* entry controls */ |
| 2292 | rdmsr(MSR_IA32_VMX_ENTRY_CTLS, | 2299 | rdmsr(MSR_IA32_VMX_ENTRY_CTLS, |
| @@ -2300,6 +2307,8 @@ static __init void nested_vmx_setup_ctls_msrs(void) | |||
| 2300 | VM_ENTRY_LOAD_IA32_PAT; | 2307 | VM_ENTRY_LOAD_IA32_PAT; |
| 2301 | nested_vmx_entry_ctls_high |= (VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR | | 2308 | nested_vmx_entry_ctls_high |= (VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR | |
| 2302 | VM_ENTRY_LOAD_IA32_EFER); | 2309 | VM_ENTRY_LOAD_IA32_EFER); |
| 2310 | if (vmx_mpx_supported()) | ||
| 2311 | nested_vmx_entry_ctls_high |= VM_ENTRY_LOAD_BNDCFGS; | ||
| 2303 | 2312 | ||
| 2304 | /* cpu-based controls */ | 2313 | /* cpu-based controls */ |
| 2305 | rdmsr(MSR_IA32_VMX_PROCBASED_CTLS, | 2314 | rdmsr(MSR_IA32_VMX_PROCBASED_CTLS, |
| @@ -2493,6 +2502,8 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) | |||
| 2493 | data = vmcs_readl(GUEST_SYSENTER_ESP); | 2502 | data = vmcs_readl(GUEST_SYSENTER_ESP); |
| 2494 | break; | 2503 | break; |
| 2495 | case MSR_IA32_BNDCFGS: | 2504 | case MSR_IA32_BNDCFGS: |
| 2505 | if (!vmx_mpx_supported()) | ||
| 2506 | return 1; | ||
| 2496 | data = vmcs_read64(GUEST_BNDCFGS); | 2507 | data = vmcs_read64(GUEST_BNDCFGS); |
| 2497 | break; | 2508 | break; |
| 2498 | case MSR_IA32_FEATURE_CONTROL: | 2509 | case MSR_IA32_FEATURE_CONTROL: |
| @@ -2564,6 +2575,8 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) | |||
| 2564 | vmcs_writel(GUEST_SYSENTER_ESP, data); | 2575 | vmcs_writel(GUEST_SYSENTER_ESP, data); |
| 2565 | break; | 2576 | break; |
| 2566 | case MSR_IA32_BNDCFGS: | 2577 | case MSR_IA32_BNDCFGS: |
| 2578 | if (!vmx_mpx_supported()) | ||
| 2579 | return 1; | ||
| 2567 | vmcs_write64(GUEST_BNDCFGS, data); | 2580 | vmcs_write64(GUEST_BNDCFGS, data); |
| 2568 | break; | 2581 | break; |
| 2569 | case MSR_IA32_TSC: | 2582 | case MSR_IA32_TSC: |
| @@ -7866,6 +7879,9 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) | |||
| 7866 | 7879 | ||
| 7867 | set_cr4_guest_host_mask(vmx); | 7880 | set_cr4_guest_host_mask(vmx); |
| 7868 | 7881 | ||
| 7882 | if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_BNDCFGS) | ||
| 7883 | vmcs_write64(GUEST_BNDCFGS, vmcs12->guest_bndcfgs); | ||
| 7884 | |||
| 7869 | if (vmcs12->cpu_based_vm_exec_control & CPU_BASED_USE_TSC_OFFSETING) | 7885 | if (vmcs12->cpu_based_vm_exec_control & CPU_BASED_USE_TSC_OFFSETING) |
| 7870 | vmcs_write64(TSC_OFFSET, | 7886 | vmcs_write64(TSC_OFFSET, |
| 7871 | vmx->nested.vmcs01_tsc_offset + vmcs12->tsc_offset); | 7887 | vmx->nested.vmcs01_tsc_offset + vmcs12->tsc_offset); |
| @@ -8351,6 +8367,8 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, | |||
| 8351 | vmcs12->guest_sysenter_cs = vmcs_read32(GUEST_SYSENTER_CS); | 8367 | vmcs12->guest_sysenter_cs = vmcs_read32(GUEST_SYSENTER_CS); |
| 8352 | vmcs12->guest_sysenter_esp = vmcs_readl(GUEST_SYSENTER_ESP); | 8368 | vmcs12->guest_sysenter_esp = vmcs_readl(GUEST_SYSENTER_ESP); |
| 8353 | vmcs12->guest_sysenter_eip = vmcs_readl(GUEST_SYSENTER_EIP); | 8369 | vmcs12->guest_sysenter_eip = vmcs_readl(GUEST_SYSENTER_EIP); |
| 8370 | if (vmx_mpx_supported()) | ||
| 8371 | vmcs12->guest_bndcfgs = vmcs_read64(GUEST_BNDCFGS); | ||
| 8354 | 8372 | ||
| 8355 | /* update exit information fields: */ | 8373 | /* update exit information fields: */ |
| 8356 | 8374 | ||
| @@ -8460,6 +8478,10 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, | |||
| 8460 | vmcs_writel(GUEST_IDTR_BASE, vmcs12->host_idtr_base); | 8478 | vmcs_writel(GUEST_IDTR_BASE, vmcs12->host_idtr_base); |
| 8461 | vmcs_writel(GUEST_GDTR_BASE, vmcs12->host_gdtr_base); | 8479 | vmcs_writel(GUEST_GDTR_BASE, vmcs12->host_gdtr_base); |
| 8462 | 8480 | ||
| 8481 | /* If not VM_EXIT_CLEAR_BNDCFGS, the L2 value propagates to L1. */ | ||
| 8482 | if (vmcs12->vm_exit_controls & VM_EXIT_CLEAR_BNDCFGS) | ||
| 8483 | vmcs_write64(GUEST_BNDCFGS, 0); | ||
| 8484 | |||
| 8463 | if (vmcs12->vm_exit_controls & VM_EXIT_LOAD_IA32_PAT) { | 8485 | if (vmcs12->vm_exit_controls & VM_EXIT_LOAD_IA32_PAT) { |
| 8464 | vmcs_write64(GUEST_IA32_PAT, vmcs12->host_ia32_pat); | 8486 | vmcs_write64(GUEST_IA32_PAT, vmcs12->host_ia32_pat); |
| 8465 | vcpu->arch.pat = vmcs12->host_ia32_pat; | 8487 | vcpu->arch.pat = vmcs12->host_ia32_pat; |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index a37da6b0165a..aa986959f237 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -3084,9 +3084,7 @@ static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu, | |||
| 3084 | * CPUID leaf 0xD, index 0, EDX:EAX. This is for compatibility | 3084 | * CPUID leaf 0xD, index 0, EDX:EAX. This is for compatibility |
| 3085 | * with old userspace. | 3085 | * with old userspace. |
| 3086 | */ | 3086 | */ |
| 3087 | if (xstate_bv & ~KVM_SUPPORTED_XCR0) | 3087 | if (xstate_bv & ~kvm_supported_xcr0()) |
| 3088 | return -EINVAL; | ||
| 3089 | if (xstate_bv & ~host_xcr0) | ||
| 3090 | return -EINVAL; | 3088 | return -EINVAL; |
| 3091 | memcpy(&vcpu->arch.guest_fpu.state->xsave, | 3089 | memcpy(&vcpu->arch.guest_fpu.state->xsave, |
| 3092 | guest_xsave->region, vcpu->arch.guest_xstate_size); | 3090 | guest_xsave->region, vcpu->arch.guest_xstate_size); |
| @@ -3939,6 +3937,23 @@ static void kvm_init_msr_list(void) | |||
| 3939 | for (i = j = KVM_SAVE_MSRS_BEGIN; i < ARRAY_SIZE(msrs_to_save); i++) { | 3937 | for (i = j = KVM_SAVE_MSRS_BEGIN; i < ARRAY_SIZE(msrs_to_save); i++) { |
| 3940 | if (rdmsr_safe(msrs_to_save[i], &dummy[0], &dummy[1]) < 0) | 3938 | if (rdmsr_safe(msrs_to_save[i], &dummy[0], &dummy[1]) < 0) |
| 3941 | continue; | 3939 | continue; |
| 3940 | |||
| 3941 | /* | ||
| 3942 | * Even MSRs that are valid in the host may not be exposed | ||
| 3943 | * to the guests in some cases. We could work around this | ||
| 3944 | * in VMX with the generic MSR save/load machinery, but it | ||
| 3945 | * is not really worthwhile since it will really only | ||
| 3946 | * happen with nested virtualization. | ||
| 3947 | */ | ||
| 3948 | switch (msrs_to_save[i]) { | ||
| 3949 | case MSR_IA32_BNDCFGS: | ||
| 3950 | if (!kvm_x86_ops->mpx_supported()) | ||
| 3951 | continue; | ||
| 3952 | break; | ||
| 3953 | default: | ||
| 3954 | break; | ||
| 3955 | } | ||
| 3956 | |||
| 3942 | if (j < i) | 3957 | if (j < i) |
| 3943 | msrs_to_save[j] = msrs_to_save[i]; | 3958 | msrs_to_save[j] = msrs_to_save[i]; |
| 3944 | j++; | 3959 | j++; |
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index 392ecbff0030..8c97bac9a895 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h | |||
| @@ -126,6 +126,8 @@ int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt, | |||
| 126 | | XSTATE_BNDREGS | XSTATE_BNDCSR) | 126 | | XSTATE_BNDREGS | XSTATE_BNDCSR) |
| 127 | extern u64 host_xcr0; | 127 | extern u64 host_xcr0; |
| 128 | 128 | ||
| 129 | extern u64 kvm_supported_xcr0(void); | ||
| 130 | |||
| 129 | extern unsigned int min_timer_period_us; | 131 | extern unsigned int min_timer_period_us; |
| 130 | 132 | ||
| 131 | extern struct static_key kvm_no_apic_vcpu; | 133 | extern struct static_key kvm_no_apic_vcpu; |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 9816b68b085f..7d21cf9f4380 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
| @@ -297,6 +297,14 @@ static inline unsigned long kvm_dirty_bitmap_bytes(struct kvm_memory_slot *memsl | |||
| 297 | return ALIGN(memslot->npages, BITS_PER_LONG) / 8; | 297 | return ALIGN(memslot->npages, BITS_PER_LONG) / 8; |
| 298 | } | 298 | } |
| 299 | 299 | ||
| 300 | struct kvm_s390_adapter_int { | ||
| 301 | u64 ind_addr; | ||
| 302 | u64 summary_addr; | ||
| 303 | u64 ind_offset; | ||
| 304 | u32 summary_offset; | ||
| 305 | u32 adapter_id; | ||
| 306 | }; | ||
| 307 | |||
| 300 | struct kvm_kernel_irq_routing_entry { | 308 | struct kvm_kernel_irq_routing_entry { |
| 301 | u32 gsi; | 309 | u32 gsi; |
| 302 | u32 type; | 310 | u32 type; |
| @@ -309,6 +317,7 @@ struct kvm_kernel_irq_routing_entry { | |||
| 309 | unsigned pin; | 317 | unsigned pin; |
| 310 | } irqchip; | 318 | } irqchip; |
| 311 | struct msi_msg msi; | 319 | struct msi_msg msi; |
| 320 | struct kvm_s390_adapter_int adapter; | ||
| 312 | }; | 321 | }; |
| 313 | struct hlist_node link; | 322 | struct hlist_node link; |
| 314 | }; | 323 | }; |
| @@ -913,7 +922,11 @@ static inline int mmu_notifier_retry(struct kvm *kvm, unsigned long mmu_seq) | |||
| 913 | 922 | ||
| 914 | #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING | 923 | #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING |
| 915 | 924 | ||
| 925 | #ifdef CONFIG_S390 | ||
| 926 | #define KVM_MAX_IRQ_ROUTES 4096 //FIXME: we can have more than that... | ||
| 927 | #else | ||
| 916 | #define KVM_MAX_IRQ_ROUTES 1024 | 928 | #define KVM_MAX_IRQ_ROUTES 1024 |
| 929 | #endif | ||
| 917 | 930 | ||
| 918 | int kvm_setup_default_irq_routing(struct kvm *kvm); | 931 | int kvm_setup_default_irq_routing(struct kvm *kvm); |
| 919 | int kvm_set_irq_routing(struct kvm *kvm, | 932 | int kvm_set_irq_routing(struct kvm *kvm, |
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index a7518be31d53..a8f4ee5d2e82 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h | |||
| @@ -741,6 +741,8 @@ struct kvm_ppc_smmu_info { | |||
| 741 | #define KVM_CAP_EXT_EMUL_CPUID 95 | 741 | #define KVM_CAP_EXT_EMUL_CPUID 95 |
| 742 | #define KVM_CAP_HYPERV_TIME 96 | 742 | #define KVM_CAP_HYPERV_TIME 96 |
| 743 | #define KVM_CAP_IOAPIC_POLARITY_IGNORED 97 | 743 | #define KVM_CAP_IOAPIC_POLARITY_IGNORED 97 |
| 744 | #define KVM_CAP_ENABLE_CAP_VM 98 | ||
| 745 | #define KVM_CAP_S390_IRQCHIP 99 | ||
| 744 | 746 | ||
| 745 | #ifdef KVM_CAP_IRQ_ROUTING | 747 | #ifdef KVM_CAP_IRQ_ROUTING |
| 746 | 748 | ||
| @@ -756,9 +758,18 @@ struct kvm_irq_routing_msi { | |||
| 756 | __u32 pad; | 758 | __u32 pad; |
| 757 | }; | 759 | }; |
| 758 | 760 | ||
| 761 | struct kvm_irq_routing_s390_adapter { | ||
| 762 | __u64 ind_addr; | ||
| 763 | __u64 summary_addr; | ||
| 764 | __u64 ind_offset; | ||
| 765 | __u32 summary_offset; | ||
| 766 | __u32 adapter_id; | ||
| 767 | }; | ||
| 768 | |||
| 759 | /* gsi routing entry types */ | 769 | /* gsi routing entry types */ |
| 760 | #define KVM_IRQ_ROUTING_IRQCHIP 1 | 770 | #define KVM_IRQ_ROUTING_IRQCHIP 1 |
| 761 | #define KVM_IRQ_ROUTING_MSI 2 | 771 | #define KVM_IRQ_ROUTING_MSI 2 |
| 772 | #define KVM_IRQ_ROUTING_S390_ADAPTER 3 | ||
| 762 | 773 | ||
| 763 | struct kvm_irq_routing_entry { | 774 | struct kvm_irq_routing_entry { |
| 764 | __u32 gsi; | 775 | __u32 gsi; |
| @@ -768,6 +779,7 @@ struct kvm_irq_routing_entry { | |||
| 768 | union { | 779 | union { |
| 769 | struct kvm_irq_routing_irqchip irqchip; | 780 | struct kvm_irq_routing_irqchip irqchip; |
| 770 | struct kvm_irq_routing_msi msi; | 781 | struct kvm_irq_routing_msi msi; |
| 782 | struct kvm_irq_routing_s390_adapter adapter; | ||
| 771 | __u32 pad[8]; | 783 | __u32 pad[8]; |
| 772 | } u; | 784 | } u; |
| 773 | }; | 785 | }; |
| @@ -1076,6 +1088,10 @@ struct kvm_s390_ucas_mapping { | |||
| 1076 | /* Available with KVM_CAP_DEBUGREGS */ | 1088 | /* Available with KVM_CAP_DEBUGREGS */ |
| 1077 | #define KVM_GET_DEBUGREGS _IOR(KVMIO, 0xa1, struct kvm_debugregs) | 1089 | #define KVM_GET_DEBUGREGS _IOR(KVMIO, 0xa1, struct kvm_debugregs) |
| 1078 | #define KVM_SET_DEBUGREGS _IOW(KVMIO, 0xa2, struct kvm_debugregs) | 1090 | #define KVM_SET_DEBUGREGS _IOW(KVMIO, 0xa2, struct kvm_debugregs) |
| 1091 | /* | ||
| 1092 | * vcpu version available with KVM_ENABLE_CAP | ||
| 1093 | * vm version available with KVM_CAP_ENABLE_CAP_VM | ||
| 1094 | */ | ||
| 1079 | #define KVM_ENABLE_CAP _IOW(KVMIO, 0xa3, struct kvm_enable_cap) | 1095 | #define KVM_ENABLE_CAP _IOW(KVMIO, 0xa3, struct kvm_enable_cap) |
| 1080 | /* Available with KVM_CAP_XSAVE */ | 1096 | /* Available with KVM_CAP_XSAVE */ |
| 1081 | #define KVM_GET_XSAVE _IOR(KVMIO, 0xa4, struct kvm_xsave) | 1097 | #define KVM_GET_XSAVE _IOR(KVMIO, 0xa4, struct kvm_xsave) |
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index abe4d6043b36..29c2a04e036e 100644 --- a/virt/kvm/eventfd.c +++ b/virt/kvm/eventfd.c | |||
| @@ -391,19 +391,19 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args) | |||
| 391 | lockdep_is_held(&kvm->irqfds.lock)); | 391 | lockdep_is_held(&kvm->irqfds.lock)); |
| 392 | irqfd_update(kvm, irqfd, irq_rt); | 392 | irqfd_update(kvm, irqfd, irq_rt); |
| 393 | 393 | ||
| 394 | events = f.file->f_op->poll(f.file, &irqfd->pt); | ||
| 395 | |||
| 396 | list_add_tail(&irqfd->list, &kvm->irqfds.items); | 394 | list_add_tail(&irqfd->list, &kvm->irqfds.items); |
| 397 | 395 | ||
| 396 | spin_unlock_irq(&kvm->irqfds.lock); | ||
| 397 | |||
| 398 | /* | 398 | /* |
| 399 | * Check if there was an event already pending on the eventfd | 399 | * Check if there was an event already pending on the eventfd |
| 400 | * before we registered, and trigger it as if we didn't miss it. | 400 | * before we registered, and trigger it as if we didn't miss it. |
| 401 | */ | 401 | */ |
| 402 | events = f.file->f_op->poll(f.file, &irqfd->pt); | ||
| 403 | |||
| 402 | if (events & POLLIN) | 404 | if (events & POLLIN) |
| 403 | schedule_work(&irqfd->inject); | 405 | schedule_work(&irqfd->inject); |
| 404 | 406 | ||
| 405 | spin_unlock_irq(&kvm->irqfds.lock); | ||
| 406 | |||
| 407 | /* | 407 | /* |
| 408 | * do not drop the file until the irqfd is fully initialized, otherwise | 408 | * do not drop the file until the irqfd is fully initialized, otherwise |
| 409 | * we might race against the POLLHUP | 409 | * we might race against the POLLHUP |
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index 1539d3757a04..d4b601547f1f 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c | |||
| @@ -50,7 +50,7 @@ | |||
| 50 | #else | 50 | #else |
| 51 | #define ioapic_debug(fmt, arg...) | 51 | #define ioapic_debug(fmt, arg...) |
| 52 | #endif | 52 | #endif |
| 53 | static int ioapic_deliver(struct kvm_ioapic *vioapic, int irq, | 53 | static int ioapic_service(struct kvm_ioapic *vioapic, int irq, |
| 54 | bool line_status); | 54 | bool line_status); |
| 55 | 55 | ||
| 56 | static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic, | 56 | static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic, |
| @@ -163,23 +163,67 @@ static bool rtc_irq_check_coalesced(struct kvm_ioapic *ioapic) | |||
| 163 | return false; | 163 | return false; |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | static int ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx, | 166 | static int ioapic_set_irq(struct kvm_ioapic *ioapic, unsigned int irq, |
| 167 | bool line_status) | 167 | int irq_level, bool line_status) |
| 168 | { | 168 | { |
| 169 | union kvm_ioapic_redirect_entry *pent; | 169 | union kvm_ioapic_redirect_entry entry; |
| 170 | int injected = -1; | 170 | u32 mask = 1 << irq; |
| 171 | u32 old_irr; | ||
| 172 | int edge, ret; | ||
| 171 | 173 | ||
| 172 | pent = &ioapic->redirtbl[idx]; | 174 | entry = ioapic->redirtbl[irq]; |
| 175 | edge = (entry.fields.trig_mode == IOAPIC_EDGE_TRIG); | ||
| 173 | 176 | ||
| 174 | if (!pent->fields.mask) { | 177 | if (!irq_level) { |
| 175 | injected = ioapic_deliver(ioapic, idx, line_status); | 178 | ioapic->irr &= ~mask; |
| 176 | if (injected && pent->fields.trig_mode == IOAPIC_LEVEL_TRIG) | 179 | ret = 1; |
| 177 | pent->fields.remote_irr = 1; | 180 | goto out; |
| 181 | } | ||
| 182 | |||
| 183 | /* | ||
| 184 | * Return 0 for coalesced interrupts; for edge-triggered interrupts, | ||
| 185 | * this only happens if a previous edge has not been delivered due | ||
| 186 | * do masking. For level interrupts, the remote_irr field tells | ||
| 187 | * us if the interrupt is waiting for an EOI. | ||
| 188 | * | ||
| 189 | * RTC is special: it is edge-triggered, but userspace likes to know | ||
| 190 | * if it has been already ack-ed via EOI because coalesced RTC | ||
| 191 | * interrupts lead to time drift in Windows guests. So we track | ||
| 192 | * EOI manually for the RTC interrupt. | ||
| 193 | */ | ||
| 194 | if (irq == RTC_GSI && line_status && | ||
| 195 | rtc_irq_check_coalesced(ioapic)) { | ||
| 196 | ret = 0; | ||
| 197 | goto out; | ||
| 178 | } | 198 | } |
| 179 | 199 | ||
| 180 | return injected; | 200 | old_irr = ioapic->irr; |
| 201 | ioapic->irr |= mask; | ||
| 202 | if ((edge && old_irr == ioapic->irr) || | ||
| 203 | (!edge && entry.fields.remote_irr)) { | ||
| 204 | ret = 0; | ||
| 205 | goto out; | ||
| 206 | } | ||
| 207 | |||
| 208 | ret = ioapic_service(ioapic, irq, line_status); | ||
| 209 | |||
| 210 | out: | ||
| 211 | trace_kvm_ioapic_set_irq(entry.bits, irq, ret == 0); | ||
| 212 | return ret; | ||
| 213 | } | ||
| 214 | |||
| 215 | static void kvm_ioapic_inject_all(struct kvm_ioapic *ioapic, unsigned long irr) | ||
| 216 | { | ||
| 217 | u32 idx; | ||
| 218 | |||
| 219 | rtc_irq_eoi_tracking_reset(ioapic); | ||
| 220 | for_each_set_bit(idx, &irr, IOAPIC_NUM_PINS) | ||
| 221 | ioapic_set_irq(ioapic, idx, 1, true); | ||
| 222 | |||
| 223 | kvm_rtc_eoi_tracking_restore_all(ioapic); | ||
| 181 | } | 224 | } |
| 182 | 225 | ||
| 226 | |||
| 183 | static void update_handled_vectors(struct kvm_ioapic *ioapic) | 227 | static void update_handled_vectors(struct kvm_ioapic *ioapic) |
| 184 | { | 228 | { |
| 185 | DECLARE_BITMAP(handled_vectors, 256); | 229 | DECLARE_BITMAP(handled_vectors, 256); |
| @@ -282,12 +326,15 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) | |||
| 282 | } | 326 | } |
| 283 | } | 327 | } |
| 284 | 328 | ||
| 285 | static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq, bool line_status) | 329 | static int ioapic_service(struct kvm_ioapic *ioapic, int irq, bool line_status) |
| 286 | { | 330 | { |
| 287 | union kvm_ioapic_redirect_entry *entry = &ioapic->redirtbl[irq]; | 331 | union kvm_ioapic_redirect_entry *entry = &ioapic->redirtbl[irq]; |
| 288 | struct kvm_lapic_irq irqe; | 332 | struct kvm_lapic_irq irqe; |
| 289 | int ret; | 333 | int ret; |
| 290 | 334 | ||
| 335 | if (entry->fields.mask) | ||
| 336 | return -1; | ||
| 337 | |||
| 291 | ioapic_debug("dest=%x dest_mode=%x delivery_mode=%x " | 338 | ioapic_debug("dest=%x dest_mode=%x delivery_mode=%x " |
| 292 | "vector=%x trig_mode=%x\n", | 339 | "vector=%x trig_mode=%x\n", |
| 293 | entry->fields.dest_id, entry->fields.dest_mode, | 340 | entry->fields.dest_id, entry->fields.dest_mode, |
| @@ -302,6 +349,9 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq, bool line_status) | |||
| 302 | irqe.level = 1; | 349 | irqe.level = 1; |
| 303 | irqe.shorthand = 0; | 350 | irqe.shorthand = 0; |
| 304 | 351 | ||
| 352 | if (irqe.trig_mode == IOAPIC_EDGE_TRIG) | ||
| 353 | ioapic->irr &= ~(1 << irq); | ||
| 354 | |||
| 305 | if (irq == RTC_GSI && line_status) { | 355 | if (irq == RTC_GSI && line_status) { |
| 306 | BUG_ON(ioapic->rtc_status.pending_eoi != 0); | 356 | BUG_ON(ioapic->rtc_status.pending_eoi != 0); |
| 307 | ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe, | 357 | ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe, |
| @@ -310,44 +360,24 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq, bool line_status) | |||
| 310 | } else | 360 | } else |
| 311 | ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe, NULL); | 361 | ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe, NULL); |
| 312 | 362 | ||
| 363 | if (ret && irqe.trig_mode == IOAPIC_LEVEL_TRIG) | ||
| 364 | entry->fields.remote_irr = 1; | ||
| 365 | |||
| 313 | return ret; | 366 | return ret; |
| 314 | } | 367 | } |
| 315 | 368 | ||
| 316 | int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int irq_source_id, | 369 | int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int irq_source_id, |
| 317 | int level, bool line_status) | 370 | int level, bool line_status) |
| 318 | { | 371 | { |
| 319 | u32 old_irr; | ||
| 320 | u32 mask = 1 << irq; | ||
| 321 | union kvm_ioapic_redirect_entry entry; | ||
| 322 | int ret, irq_level; | 372 | int ret, irq_level; |
| 323 | 373 | ||
| 324 | BUG_ON(irq < 0 || irq >= IOAPIC_NUM_PINS); | 374 | BUG_ON(irq < 0 || irq >= IOAPIC_NUM_PINS); |
| 325 | 375 | ||
| 326 | spin_lock(&ioapic->lock); | 376 | spin_lock(&ioapic->lock); |
| 327 | old_irr = ioapic->irr; | ||
| 328 | irq_level = __kvm_irq_line_state(&ioapic->irq_states[irq], | 377 | irq_level = __kvm_irq_line_state(&ioapic->irq_states[irq], |
| 329 | irq_source_id, level); | 378 | irq_source_id, level); |
| 330 | entry = ioapic->redirtbl[irq]; | 379 | ret = ioapic_set_irq(ioapic, irq, irq_level, line_status); |
| 331 | if (!irq_level) { | ||
| 332 | ioapic->irr &= ~mask; | ||
| 333 | ret = 1; | ||
| 334 | } else { | ||
| 335 | int edge = (entry.fields.trig_mode == IOAPIC_EDGE_TRIG); | ||
| 336 | 380 | ||
| 337 | if (irq == RTC_GSI && line_status && | ||
| 338 | rtc_irq_check_coalesced(ioapic)) { | ||
| 339 | ret = 0; /* coalesced */ | ||
| 340 | goto out; | ||
| 341 | } | ||
| 342 | ioapic->irr |= mask; | ||
| 343 | if ((edge && old_irr != ioapic->irr) || | ||
| 344 | (!edge && !entry.fields.remote_irr)) | ||
| 345 | ret = ioapic_service(ioapic, irq, line_status); | ||
| 346 | else | ||
| 347 | ret = 0; /* report coalesced interrupt */ | ||
| 348 | } | ||
| 349 | out: | ||
| 350 | trace_kvm_ioapic_set_irq(entry.bits, irq, ret == 0); | ||
| 351 | spin_unlock(&ioapic->lock); | 381 | spin_unlock(&ioapic->lock); |
| 352 | 382 | ||
| 353 | return ret; | 383 | return ret; |
| @@ -393,7 +423,7 @@ static void __kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, | |||
| 393 | 423 | ||
| 394 | ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG); | 424 | ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG); |
| 395 | ent->fields.remote_irr = 0; | 425 | ent->fields.remote_irr = 0; |
| 396 | if (!ent->fields.mask && (ioapic->irr & (1 << i))) | 426 | if (ioapic->irr & (1 << i)) |
| 397 | ioapic_service(ioapic, i, false); | 427 | ioapic_service(ioapic, i, false); |
| 398 | } | 428 | } |
| 399 | } | 429 | } |
| @@ -594,9 +624,10 @@ int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state) | |||
| 594 | 624 | ||
| 595 | spin_lock(&ioapic->lock); | 625 | spin_lock(&ioapic->lock); |
| 596 | memcpy(ioapic, state, sizeof(struct kvm_ioapic_state)); | 626 | memcpy(ioapic, state, sizeof(struct kvm_ioapic_state)); |
| 627 | ioapic->irr = 0; | ||
| 597 | update_handled_vectors(ioapic); | 628 | update_handled_vectors(ioapic); |
| 598 | kvm_vcpu_request_scan_ioapic(kvm); | 629 | kvm_vcpu_request_scan_ioapic(kvm); |
| 599 | kvm_rtc_eoi_tracking_restore_all(ioapic); | 630 | kvm_ioapic_inject_all(ioapic, state->irr); |
| 600 | spin_unlock(&ioapic->lock); | 631 | spin_unlock(&ioapic->lock); |
| 601 | return 0; | 632 | return 0; |
| 602 | } | 633 | } |
