diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-18 19:05:28 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-18 19:05:28 -0500 |
commit | 66dcff86ba40eebb5133cccf450878f2bba102ef (patch) | |
tree | e7eb49ad9316989a529b00303d2dd2cffa61a7f5 | |
parent | 91ed9e8a32d9a76adc59c83f8b40024076cf8a02 (diff) | |
parent | 2c4aa55a6af070262cca425745e8e54310e96b8d (diff) |
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM update from Paolo Bonzini:
"3.19 changes for KVM:
- spring cleaning: removed support for IA64, and for hardware-
assisted virtualization on the PPC970
- ARM, PPC, s390 all had only small fixes
For x86:
- small performance improvements (though only on weird guests)
- usual round of hardware-compliancy fixes from Nadav
- APICv fixes
- XSAVES support for hosts and guests. XSAVES hosts were broken
because the (non-KVM) XSAVES patches inadvertently changed the KVM
userspace ABI whenever XSAVES was enabled; hence, this part is
going to stable. Guest support is just a matter of exposing the
feature and CPUID leaves support"
* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (179 commits)
KVM: move APIC types to arch/x86/
KVM: PPC: Book3S: Enable in-kernel XICS emulation by default
KVM: PPC: Book3S HV: Improve H_CONFER implementation
KVM: PPC: Book3S HV: Fix endianness of instruction obtained from HEIR register
KVM: PPC: Book3S HV: Remove code for PPC970 processors
KVM: PPC: Book3S HV: Tracepoints for KVM HV guest interactions
KVM: PPC: Book3S HV: Simplify locking around stolen time calculations
arch: powerpc: kvm: book3s_paired_singles.c: Remove unused function
arch: powerpc: kvm: book3s_pr.c: Remove unused function
arch: powerpc: kvm: book3s.c: Remove some unused functions
arch: powerpc: kvm: book3s_32_mmu.c: Remove unused function
KVM: PPC: Book3S HV: Check wait conditions before sleeping in kvmppc_vcore_blocked
KVM: PPC: Book3S HV: ptes are big endian
KVM: PPC: Book3S HV: Fix inaccuracies in ICP emulation for H_IPI
KVM: PPC: Book3S HV: Fix KSM memory corruption
KVM: PPC: Book3S HV: Fix an issue where guest is paused on receiving HMI
KVM: PPC: Book3S HV: Fix computation of tlbie operand
KVM: PPC: Book3S HV: Add missing HPTE unlock
KVM: PPC: BookE: Improve irq inject tracepoint
arm/arm64: KVM: Require in-kernel vgic for the arch timers
...
114 files changed, 3551 insertions, 16095 deletions
diff --git a/Documentation/ia64/kvm.txt b/Documentation/ia64/kvm.txt deleted file mode 100644 index ffb5c80bec3e..000000000000 --- a/Documentation/ia64/kvm.txt +++ /dev/null | |||
@@ -1,83 +0,0 @@ | |||
1 | Currently, kvm module is in EXPERIMENTAL stage on IA64. This means that | ||
2 | interfaces are not stable enough to use. So, please don't run critical | ||
3 | applications in virtual machine. | ||
4 | We will try our best to improve it in future versions! | ||
5 | |||
6 | Guide: How to boot up guests on kvm/ia64 | ||
7 | |||
8 | This guide is to describe how to enable kvm support for IA-64 systems. | ||
9 | |||
10 | 1. Get the kvm source from git.kernel.org. | ||
11 | Userspace source: | ||
12 | git clone git://git.kernel.org/pub/scm/virt/kvm/kvm-userspace.git | ||
13 | Kernel Source: | ||
14 | git clone git://git.kernel.org/pub/scm/linux/kernel/git/xiantao/kvm-ia64.git | ||
15 | |||
16 | 2. Compile the source code. | ||
17 | 2.1 Compile userspace code: | ||
18 | (1)cd ./kvm-userspace | ||
19 | (2)./configure | ||
20 | (3)cd kernel | ||
21 | (4)make sync LINUX= $kernel_dir (kernel_dir is the directory of kernel source.) | ||
22 | (5)cd .. | ||
23 | (6)make qemu | ||
24 | (7)cd qemu; make install | ||
25 | |||
26 | 2.2 Compile kernel source code: | ||
27 | (1) cd ./$kernel_dir | ||
28 | (2) Make menuconfig | ||
29 | (3) Enter into virtualization option, and choose kvm. | ||
30 | (4) make | ||
31 | (5) Once (4) done, make modules_install | ||
32 | (6) Make initrd, and use new kernel to reboot up host machine. | ||
33 | (7) Once (6) done, cd $kernel_dir/arch/ia64/kvm | ||
34 | (8) insmod kvm.ko; insmod kvm-intel.ko | ||
35 | |||
36 | Note: For step 2, please make sure that host page size == TARGET_PAGE_SIZE of qemu, otherwise, may fail. | ||
37 | |||
38 | 3. Get Guest Firmware named as Flash.fd, and put it under right place: | ||
39 | (1) If you have the guest firmware (binary) released by Intel Corp for Xen, use it directly. | ||
40 | |||
41 | (2) If you have no firmware at hand, Please download its source from | ||
42 | hg clone http://xenbits.xensource.com/ext/efi-vfirmware.hg | ||
43 | you can get the firmware's binary in the directory of efi-vfirmware.hg/binaries. | ||
44 | |||
45 | (3) Rename the firmware you owned to Flash.fd, and copy it to /usr/local/share/qemu | ||
46 | |||
47 | 4. Boot up Linux or Windows guests: | ||
48 | 4.1 Create or install a image for guest boot. If you have xen experience, it should be easy. | ||
49 | |||
50 | 4.2 Boot up guests use the following command. | ||
51 | /usr/local/bin/qemu-system-ia64 -smp xx -m 512 -hda $your_image | ||
52 | (xx is the number of virtual processors for the guest, now the maximum value is 4) | ||
53 | |||
54 | 5. Known possible issue on some platforms with old Firmware. | ||
55 | |||
56 | In the event of strange host crash issues, try to solve it through either of the following ways: | ||
57 | |||
58 | (1): Upgrade your Firmware to the latest one. | ||
59 | |||
60 | (2): Applying the below patch to kernel source. | ||
61 | diff --git a/arch/ia64/kernel/pal.S b/arch/ia64/kernel/pal.S | ||
62 | index 0b53344..f02b0f7 100644 | ||
63 | --- a/arch/ia64/kernel/pal.S | ||
64 | +++ b/arch/ia64/kernel/pal.S | ||
65 | @@ -84,7 +84,8 @@ GLOBAL_ENTRY(ia64_pal_call_static) | ||
66 | mov ar.pfs = loc1 | ||
67 | mov rp = loc0 | ||
68 | ;; | ||
69 | - srlz.d // serialize restoration of psr.l | ||
70 | + srlz.i // serialize restoration of psr.l | ||
71 | + ;; | ||
72 | br.ret.sptk.many b0 | ||
73 | END(ia64_pal_call_static) | ||
74 | |||
75 | 6. Bug report: | ||
76 | If you found any issues when use kvm/ia64, Please post the bug info to kvm-ia64-devel mailing list. | ||
77 | https://lists.sourceforge.net/lists/listinfo/kvm-ia64-devel/ | ||
78 | |||
79 | Thanks for your interest! Let's work together, and make kvm/ia64 stronger and stronger! | ||
80 | |||
81 | |||
82 | Xiantao Zhang <xiantao.zhang@intel.com> | ||
83 | 2008.3.10 | ||
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 7610eaa4d491..0007fef4ed81 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt | |||
@@ -68,9 +68,12 @@ description: | |||
68 | 68 | ||
69 | Capability: which KVM extension provides this ioctl. Can be 'basic', | 69 | Capability: which KVM extension provides this ioctl. Can be 'basic', |
70 | which means that is will be provided by any kernel that supports | 70 | which means that is will be provided by any kernel that supports |
71 | API version 12 (see section 4.1), or a KVM_CAP_xyz constant, which | 71 | API version 12 (see section 4.1), a KVM_CAP_xyz constant, which |
72 | means availability needs to be checked with KVM_CHECK_EXTENSION | 72 | means availability needs to be checked with KVM_CHECK_EXTENSION |
73 | (see section 4.4). | 73 | (see section 4.4), or 'none' which means that while not all kernels |
74 | support this ioctl, there's no capability bit to check its | ||
75 | availability: for kernels that don't support the ioctl, | ||
76 | the ioctl returns -ENOTTY. | ||
74 | 77 | ||
75 | Architectures: which instruction set architectures provide this ioctl. | 78 | Architectures: which instruction set architectures provide this ioctl. |
76 | x86 includes both i386 and x86_64. | 79 | x86 includes both i386 and x86_64. |
@@ -604,7 +607,7 @@ struct kvm_fpu { | |||
604 | 4.24 KVM_CREATE_IRQCHIP | 607 | 4.24 KVM_CREATE_IRQCHIP |
605 | 608 | ||
606 | Capability: KVM_CAP_IRQCHIP, KVM_CAP_S390_IRQCHIP (s390) | 609 | Capability: KVM_CAP_IRQCHIP, KVM_CAP_S390_IRQCHIP (s390) |
607 | Architectures: x86, ia64, ARM, arm64, s390 | 610 | Architectures: x86, ARM, arm64, s390 |
608 | Type: vm ioctl | 611 | Type: vm ioctl |
609 | Parameters: none | 612 | Parameters: none |
610 | Returns: 0 on success, -1 on error | 613 | Returns: 0 on success, -1 on error |
@@ -612,7 +615,7 @@ Returns: 0 on success, -1 on error | |||
612 | Creates an interrupt controller model in the kernel. On x86, creates a virtual | 615 | Creates an interrupt controller model in the kernel. On x86, creates a virtual |
613 | ioapic, a virtual PIC (two PICs, nested), and sets up future vcpus to have a | 616 | ioapic, a virtual PIC (two PICs, nested), and sets up future vcpus to have a |
614 | local APIC. IRQ routing for GSIs 0-15 is set to both PIC and IOAPIC; GSI 16-23 | 617 | local APIC. IRQ routing for GSIs 0-15 is set to both PIC and IOAPIC; GSI 16-23 |
615 | only go to the IOAPIC. On ia64, a IOSAPIC is created. On ARM/arm64, a GIC is | 618 | only go to the IOAPIC. On ARM/arm64, a GIC is |
616 | created. On s390, a dummy irq routing table is created. | 619 | created. On s390, a dummy irq routing table is created. |
617 | 620 | ||
618 | Note that on s390 the KVM_CAP_S390_IRQCHIP vm capability needs to be enabled | 621 | Note that on s390 the KVM_CAP_S390_IRQCHIP vm capability needs to be enabled |
@@ -622,7 +625,7 @@ before KVM_CREATE_IRQCHIP can be used. | |||
622 | 4.25 KVM_IRQ_LINE | 625 | 4.25 KVM_IRQ_LINE |
623 | 626 | ||
624 | Capability: KVM_CAP_IRQCHIP | 627 | Capability: KVM_CAP_IRQCHIP |
625 | Architectures: x86, ia64, arm, arm64 | 628 | Architectures: x86, arm, arm64 |
626 | Type: vm ioctl | 629 | Type: vm ioctl |
627 | Parameters: struct kvm_irq_level | 630 | Parameters: struct kvm_irq_level |
628 | Returns: 0 on success, -1 on error | 631 | Returns: 0 on success, -1 on error |
@@ -676,7 +679,7 @@ struct kvm_irq_level { | |||
676 | 4.26 KVM_GET_IRQCHIP | 679 | 4.26 KVM_GET_IRQCHIP |
677 | 680 | ||
678 | Capability: KVM_CAP_IRQCHIP | 681 | Capability: KVM_CAP_IRQCHIP |
679 | Architectures: x86, ia64 | 682 | Architectures: x86 |
680 | Type: vm ioctl | 683 | Type: vm ioctl |
681 | Parameters: struct kvm_irqchip (in/out) | 684 | Parameters: struct kvm_irqchip (in/out) |
682 | Returns: 0 on success, -1 on error | 685 | Returns: 0 on success, -1 on error |
@@ -698,7 +701,7 @@ struct kvm_irqchip { | |||
698 | 4.27 KVM_SET_IRQCHIP | 701 | 4.27 KVM_SET_IRQCHIP |
699 | 702 | ||
700 | Capability: KVM_CAP_IRQCHIP | 703 | Capability: KVM_CAP_IRQCHIP |
701 | Architectures: x86, ia64 | 704 | Architectures: x86 |
702 | Type: vm ioctl | 705 | Type: vm ioctl |
703 | Parameters: struct kvm_irqchip (in) | 706 | Parameters: struct kvm_irqchip (in) |
704 | Returns: 0 on success, -1 on error | 707 | Returns: 0 on success, -1 on error |
@@ -991,7 +994,7 @@ for vm-wide capabilities. | |||
991 | 4.38 KVM_GET_MP_STATE | 994 | 4.38 KVM_GET_MP_STATE |
992 | 995 | ||
993 | Capability: KVM_CAP_MP_STATE | 996 | Capability: KVM_CAP_MP_STATE |
994 | Architectures: x86, ia64, s390 | 997 | Architectures: x86, s390 |
995 | Type: vcpu ioctl | 998 | Type: vcpu ioctl |
996 | Parameters: struct kvm_mp_state (out) | 999 | Parameters: struct kvm_mp_state (out) |
997 | Returns: 0 on success; -1 on error | 1000 | Returns: 0 on success; -1 on error |
@@ -1005,16 +1008,15 @@ uniprocessor guests). | |||
1005 | 1008 | ||
1006 | Possible values are: | 1009 | Possible values are: |
1007 | 1010 | ||
1008 | - KVM_MP_STATE_RUNNABLE: the vcpu is currently running [x86, ia64] | 1011 | - KVM_MP_STATE_RUNNABLE: the vcpu is currently running [x86] |
1009 | - KVM_MP_STATE_UNINITIALIZED: the vcpu is an application processor (AP) | 1012 | - KVM_MP_STATE_UNINITIALIZED: the vcpu is an application processor (AP) |
1010 | which has not yet received an INIT signal [x86, | 1013 | which has not yet received an INIT signal [x86] |
1011 | ia64] | ||
1012 | - KVM_MP_STATE_INIT_RECEIVED: the vcpu has received an INIT signal, and is | 1014 | - KVM_MP_STATE_INIT_RECEIVED: the vcpu has received an INIT signal, and is |
1013 | now ready for a SIPI [x86, ia64] | 1015 | now ready for a SIPI [x86] |
1014 | - KVM_MP_STATE_HALTED: the vcpu has executed a HLT instruction and | 1016 | - KVM_MP_STATE_HALTED: the vcpu has executed a HLT instruction and |
1015 | is waiting for an interrupt [x86, ia64] | 1017 | is waiting for an interrupt [x86] |
1016 | - KVM_MP_STATE_SIPI_RECEIVED: the vcpu has just received a SIPI (vector | 1018 | - KVM_MP_STATE_SIPI_RECEIVED: the vcpu has just received a SIPI (vector |
1017 | accessible via KVM_GET_VCPU_EVENTS) [x86, ia64] | 1019 | accessible via KVM_GET_VCPU_EVENTS) [x86] |
1018 | - KVM_MP_STATE_STOPPED: the vcpu is stopped [s390] | 1020 | - KVM_MP_STATE_STOPPED: the vcpu is stopped [s390] |
1019 | - KVM_MP_STATE_CHECK_STOP: the vcpu is in a special error state [s390] | 1021 | - KVM_MP_STATE_CHECK_STOP: the vcpu is in a special error state [s390] |
1020 | - KVM_MP_STATE_OPERATING: the vcpu is operating (running or halted) | 1022 | - KVM_MP_STATE_OPERATING: the vcpu is operating (running or halted) |
@@ -1022,7 +1024,7 @@ Possible values are: | |||
1022 | - KVM_MP_STATE_LOAD: the vcpu is in a special load/startup state | 1024 | - KVM_MP_STATE_LOAD: the vcpu is in a special load/startup state |
1023 | [s390] | 1025 | [s390] |
1024 | 1026 | ||
1025 | On x86 and ia64, this ioctl is only useful after KVM_CREATE_IRQCHIP. Without an | 1027 | On x86, this ioctl is only useful after KVM_CREATE_IRQCHIP. Without an |
1026 | in-kernel irqchip, the multiprocessing state must be maintained by userspace on | 1028 | in-kernel irqchip, the multiprocessing state must be maintained by userspace on |
1027 | these architectures. | 1029 | these architectures. |
1028 | 1030 | ||
@@ -1030,7 +1032,7 @@ these architectures. | |||
1030 | 4.39 KVM_SET_MP_STATE | 1032 | 4.39 KVM_SET_MP_STATE |
1031 | 1033 | ||
1032 | Capability: KVM_CAP_MP_STATE | 1034 | Capability: KVM_CAP_MP_STATE |
1033 | Architectures: x86, ia64, s390 | 1035 | Architectures: x86, s390 |
1034 | Type: vcpu ioctl | 1036 | Type: vcpu ioctl |
1035 | Parameters: struct kvm_mp_state (in) | 1037 | Parameters: struct kvm_mp_state (in) |
1036 | Returns: 0 on success; -1 on error | 1038 | Returns: 0 on success; -1 on error |
@@ -1038,7 +1040,7 @@ Returns: 0 on success; -1 on error | |||
1038 | Sets the vcpu's current "multiprocessing state"; see KVM_GET_MP_STATE for | 1040 | Sets the vcpu's current "multiprocessing state"; see KVM_GET_MP_STATE for |
1039 | arguments. | 1041 | arguments. |
1040 | 1042 | ||
1041 | On x86 and ia64, this ioctl is only useful after KVM_CREATE_IRQCHIP. Without an | 1043 | On x86, this ioctl is only useful after KVM_CREATE_IRQCHIP. Without an |
1042 | in-kernel irqchip, the multiprocessing state must be maintained by userspace on | 1044 | in-kernel irqchip, the multiprocessing state must be maintained by userspace on |
1043 | these architectures. | 1045 | these architectures. |
1044 | 1046 | ||
@@ -1065,7 +1067,7 @@ documentation when it pops into existence). | |||
1065 | 4.41 KVM_SET_BOOT_CPU_ID | 1067 | 4.41 KVM_SET_BOOT_CPU_ID |
1066 | 1068 | ||
1067 | Capability: KVM_CAP_SET_BOOT_CPU_ID | 1069 | Capability: KVM_CAP_SET_BOOT_CPU_ID |
1068 | Architectures: x86, ia64 | 1070 | Architectures: x86 |
1069 | Type: vm ioctl | 1071 | Type: vm ioctl |
1070 | Parameters: unsigned long vcpu_id | 1072 | Parameters: unsigned long vcpu_id |
1071 | Returns: 0 on success, -1 on error | 1073 | Returns: 0 on success, -1 on error |
@@ -1257,8 +1259,8 @@ The flags bitmap is defined as: | |||
1257 | 1259 | ||
1258 | 4.48 KVM_ASSIGN_PCI_DEVICE | 1260 | 4.48 KVM_ASSIGN_PCI_DEVICE |
1259 | 1261 | ||
1260 | Capability: KVM_CAP_DEVICE_ASSIGNMENT | 1262 | Capability: none |
1261 | Architectures: x86 ia64 | 1263 | Architectures: x86 |
1262 | Type: vm ioctl | 1264 | Type: vm ioctl |
1263 | Parameters: struct kvm_assigned_pci_dev (in) | 1265 | Parameters: struct kvm_assigned_pci_dev (in) |
1264 | Returns: 0 on success, -1 on error | 1266 | Returns: 0 on success, -1 on error |
@@ -1298,25 +1300,36 @@ Only PCI header type 0 devices with PCI BAR resources are supported by | |||
1298 | device assignment. The user requesting this ioctl must have read/write | 1300 | device assignment. The user requesting this ioctl must have read/write |
1299 | access to the PCI sysfs resource files associated with the device. | 1301 | access to the PCI sysfs resource files associated with the device. |
1300 | 1302 | ||
1303 | Errors: | ||
1304 | ENOTTY: kernel does not support this ioctl | ||
1305 | |||
1306 | Other error conditions may be defined by individual device types or | ||
1307 | have their standard meanings. | ||
1308 | |||
1301 | 1309 | ||
1302 | 4.49 KVM_DEASSIGN_PCI_DEVICE | 1310 | 4.49 KVM_DEASSIGN_PCI_DEVICE |
1303 | 1311 | ||
1304 | Capability: KVM_CAP_DEVICE_DEASSIGNMENT | 1312 | Capability: none |
1305 | Architectures: x86 ia64 | 1313 | Architectures: x86 |
1306 | Type: vm ioctl | 1314 | Type: vm ioctl |
1307 | Parameters: struct kvm_assigned_pci_dev (in) | 1315 | Parameters: struct kvm_assigned_pci_dev (in) |
1308 | Returns: 0 on success, -1 on error | 1316 | Returns: 0 on success, -1 on error |
1309 | 1317 | ||
1310 | Ends PCI device assignment, releasing all associated resources. | 1318 | Ends PCI device assignment, releasing all associated resources. |
1311 | 1319 | ||
1312 | See KVM_CAP_DEVICE_ASSIGNMENT for the data structure. Only assigned_dev_id is | 1320 | See KVM_ASSIGN_PCI_DEVICE for the data structure. Only assigned_dev_id is |
1313 | used in kvm_assigned_pci_dev to identify the device. | 1321 | used in kvm_assigned_pci_dev to identify the device. |
1314 | 1322 | ||
1323 | Errors: | ||
1324 | ENOTTY: kernel does not support this ioctl | ||
1325 | |||
1326 | Other error conditions may be defined by individual device types or | ||
1327 | have their standard meanings. | ||
1315 | 1328 | ||
1316 | 4.50 KVM_ASSIGN_DEV_IRQ | 1329 | 4.50 KVM_ASSIGN_DEV_IRQ |
1317 | 1330 | ||
1318 | Capability: KVM_CAP_ASSIGN_DEV_IRQ | 1331 | Capability: KVM_CAP_ASSIGN_DEV_IRQ |
1319 | Architectures: x86 ia64 | 1332 | Architectures: x86 |
1320 | Type: vm ioctl | 1333 | Type: vm ioctl |
1321 | Parameters: struct kvm_assigned_irq (in) | 1334 | Parameters: struct kvm_assigned_irq (in) |
1322 | Returns: 0 on success, -1 on error | 1335 | Returns: 0 on success, -1 on error |
@@ -1346,11 +1359,17 @@ The following flags are defined: | |||
1346 | It is not valid to specify multiple types per host or guest IRQ. However, the | 1359 | It is not valid to specify multiple types per host or guest IRQ. However, the |
1347 | IRQ type of host and guest can differ or can even be null. | 1360 | IRQ type of host and guest can differ or can even be null. |
1348 | 1361 | ||
1362 | Errors: | ||
1363 | ENOTTY: kernel does not support this ioctl | ||
1364 | |||
1365 | Other error conditions may be defined by individual device types or | ||
1366 | have their standard meanings. | ||
1367 | |||
1349 | 1368 | ||
1350 | 4.51 KVM_DEASSIGN_DEV_IRQ | 1369 | 4.51 KVM_DEASSIGN_DEV_IRQ |
1351 | 1370 | ||
1352 | Capability: KVM_CAP_ASSIGN_DEV_IRQ | 1371 | Capability: KVM_CAP_ASSIGN_DEV_IRQ |
1353 | Architectures: x86 ia64 | 1372 | Architectures: x86 |
1354 | Type: vm ioctl | 1373 | Type: vm ioctl |
1355 | Parameters: struct kvm_assigned_irq (in) | 1374 | Parameters: struct kvm_assigned_irq (in) |
1356 | Returns: 0 on success, -1 on error | 1375 | Returns: 0 on success, -1 on error |
@@ -1365,7 +1384,7 @@ KVM_ASSIGN_DEV_IRQ. Partial deassignment of host or guest IRQ is allowed. | |||
1365 | 4.52 KVM_SET_GSI_ROUTING | 1384 | 4.52 KVM_SET_GSI_ROUTING |
1366 | 1385 | ||
1367 | Capability: KVM_CAP_IRQ_ROUTING | 1386 | Capability: KVM_CAP_IRQ_ROUTING |
1368 | Architectures: x86 ia64 s390 | 1387 | Architectures: x86 s390 |
1369 | Type: vm ioctl | 1388 | Type: vm ioctl |
1370 | Parameters: struct kvm_irq_routing (in) | 1389 | Parameters: struct kvm_irq_routing (in) |
1371 | Returns: 0 on success, -1 on error | 1390 | Returns: 0 on success, -1 on error |
@@ -1423,8 +1442,8 @@ struct kvm_irq_routing_s390_adapter { | |||
1423 | 1442 | ||
1424 | 4.53 KVM_ASSIGN_SET_MSIX_NR | 1443 | 4.53 KVM_ASSIGN_SET_MSIX_NR |
1425 | 1444 | ||
1426 | Capability: KVM_CAP_DEVICE_MSIX | 1445 | Capability: none |
1427 | Architectures: x86 ia64 | 1446 | Architectures: x86 |
1428 | Type: vm ioctl | 1447 | Type: vm ioctl |
1429 | Parameters: struct kvm_assigned_msix_nr (in) | 1448 | Parameters: struct kvm_assigned_msix_nr (in) |
1430 | Returns: 0 on success, -1 on error | 1449 | Returns: 0 on success, -1 on error |
@@ -1445,8 +1464,8 @@ struct kvm_assigned_msix_nr { | |||
1445 | 1464 | ||
1446 | 4.54 KVM_ASSIGN_SET_MSIX_ENTRY | 1465 | 4.54 KVM_ASSIGN_SET_MSIX_ENTRY |
1447 | 1466 | ||
1448 | Capability: KVM_CAP_DEVICE_MSIX | 1467 | Capability: none |
1449 | Architectures: x86 ia64 | 1468 | Architectures: x86 |
1450 | Type: vm ioctl | 1469 | Type: vm ioctl |
1451 | Parameters: struct kvm_assigned_msix_entry (in) | 1470 | Parameters: struct kvm_assigned_msix_entry (in) |
1452 | Returns: 0 on success, -1 on error | 1471 | Returns: 0 on success, -1 on error |
@@ -1461,6 +1480,12 @@ struct kvm_assigned_msix_entry { | |||
1461 | __u16 padding[3]; | 1480 | __u16 padding[3]; |
1462 | }; | 1481 | }; |
1463 | 1482 | ||
1483 | Errors: | ||
1484 | ENOTTY: kernel does not support this ioctl | ||
1485 | |||
1486 | Other error conditions may be defined by individual device types or | ||
1487 | have their standard meanings. | ||
1488 | |||
1464 | 1489 | ||
1465 | 4.55 KVM_SET_TSC_KHZ | 1490 | 4.55 KVM_SET_TSC_KHZ |
1466 | 1491 | ||
@@ -2453,9 +2478,15 @@ return ENOEXEC for that vcpu. | |||
2453 | Note that because some registers reflect machine topology, all vcpus | 2478 | Note that because some registers reflect machine topology, all vcpus |
2454 | should be created before this ioctl is invoked. | 2479 | should be created before this ioctl is invoked. |
2455 | 2480 | ||
2481 | Userspace can call this function multiple times for a given vcpu, including | ||
2482 | after the vcpu has been run. This will reset the vcpu to its initial | ||
2483 | state. All calls to this function after the initial call must use the same | ||
2484 | target and same set of feature flags, otherwise EINVAL will be returned. | ||
2485 | |||
2456 | Possible features: | 2486 | Possible features: |
2457 | - KVM_ARM_VCPU_POWER_OFF: Starts the CPU in a power-off state. | 2487 | - KVM_ARM_VCPU_POWER_OFF: Starts the CPU in a power-off state. |
2458 | Depends on KVM_CAP_ARM_PSCI. | 2488 | Depends on KVM_CAP_ARM_PSCI. If not set, the CPU will be powered on |
2489 | and execute guest code when KVM_RUN is called. | ||
2459 | - KVM_ARM_VCPU_EL1_32BIT: Starts the CPU in a 32bit mode. | 2490 | - KVM_ARM_VCPU_EL1_32BIT: Starts the CPU in a 32bit mode. |
2460 | Depends on KVM_CAP_ARM_EL1_32BIT (arm64 only). | 2491 | Depends on KVM_CAP_ARM_EL1_32BIT (arm64 only). |
2461 | - KVM_ARM_VCPU_PSCI_0_2: Emulate PSCI v0.2 for the CPU. | 2492 | - KVM_ARM_VCPU_PSCI_0_2: Emulate PSCI v0.2 for the CPU. |
@@ -2951,6 +2982,15 @@ HVC instruction based PSCI call from the vcpu. The 'type' field describes | |||
2951 | the system-level event type. The 'flags' field describes architecture | 2982 | the system-level event type. The 'flags' field describes architecture |
2952 | specific flags for the system-level event. | 2983 | specific flags for the system-level event. |
2953 | 2984 | ||
2985 | Valid values for 'type' are: | ||
2986 | KVM_SYSTEM_EVENT_SHUTDOWN -- the guest has requested a shutdown of the | ||
2987 | VM. Userspace is not obliged to honour this, and if it does honour | ||
2988 | this does not need to destroy the VM synchronously (ie it may call | ||
2989 | KVM_RUN again before shutdown finally occurs). | ||
2990 | KVM_SYSTEM_EVENT_RESET -- the guest has requested a reset of the VM. | ||
2991 | As with SHUTDOWN, userspace can choose to ignore the request, or | ||
2992 | to schedule the reset to occur in the future and may call KVM_RUN again. | ||
2993 | |||
2954 | /* Fix the size of the union. */ | 2994 | /* Fix the size of the union. */ |
2955 | char padding[256]; | 2995 | char padding[256]; |
2956 | }; | 2996 | }; |
diff --git a/Documentation/virtual/kvm/devices/vm.txt b/Documentation/virtual/kvm/devices/vm.txt index 0d16f96c0eac..d426fc87fe93 100644 --- a/Documentation/virtual/kvm/devices/vm.txt +++ b/Documentation/virtual/kvm/devices/vm.txt | |||
@@ -12,14 +12,14 @@ specific. | |||
12 | 1. GROUP: KVM_S390_VM_MEM_CTRL | 12 | 1. GROUP: KVM_S390_VM_MEM_CTRL |
13 | Architectures: s390 | 13 | Architectures: s390 |
14 | 14 | ||
15 | 1.1. ATTRIBUTE: KVM_S390_VM_MEM_CTRL | 15 | 1.1. ATTRIBUTE: KVM_S390_VM_MEM_ENABLE_CMMA |
16 | Parameters: none | 16 | Parameters: none |
17 | Returns: -EBUSY if already a vcpus is defined, otherwise 0 | 17 | Returns: -EBUSY if a vcpu is already defined, otherwise 0 |
18 | 18 | ||
19 | Enables CMMA for the virtual machine | 19 | Enables Collaborative Memory Management Assist (CMMA) for the virtual machine. |
20 | 20 | ||
21 | 1.2. ATTRIBUTE: KVM_S390_VM_CLR_CMMA | 21 | 1.2. ATTRIBUTE: KVM_S390_VM_MEM_CLR_CMMA |
22 | Parameteres: none | 22 | Parameters: none |
23 | Returns: 0 | 23 | Returns: 0 |
24 | 24 | ||
25 | Clear the CMMA status for all guest pages, so any pages the guest marked | 25 | Clear the CMMA status for all guest pages, so any pages the guest marked |
diff --git a/Documentation/virtual/kvm/msr.txt b/Documentation/virtual/kvm/msr.txt index 6d470ae7b073..2a71c8f29f68 100644 --- a/Documentation/virtual/kvm/msr.txt +++ b/Documentation/virtual/kvm/msr.txt | |||
@@ -168,7 +168,7 @@ MSR_KVM_ASYNC_PF_EN: 0x4b564d02 | |||
168 | 64 byte memory area which must be in guest RAM and must be | 168 | 64 byte memory area which must be in guest RAM and must be |
169 | zeroed. Bits 5-2 are reserved and should be zero. Bit 0 is 1 | 169 | zeroed. Bits 5-2 are reserved and should be zero. Bit 0 is 1 |
170 | when asynchronous page faults are enabled on the vcpu 0 when | 170 | when asynchronous page faults are enabled on the vcpu 0 when |
171 | disabled. Bit 2 is 1 if asynchronous page faults can be injected | 171 | disabled. Bit 1 is 1 if asynchronous page faults can be injected |
172 | when vcpu is in cpl == 0. | 172 | when vcpu is in cpl == 0. |
173 | 173 | ||
174 | First 4 byte of 64 byte memory location will be written to by | 174 | First 4 byte of 64 byte memory location will be written to by |
diff --git a/MAINTAINERS b/MAINTAINERS index 4507a7e87c00..7605833aabc6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -5495,15 +5495,6 @@ S: Supported | |||
5495 | F: arch/powerpc/include/asm/kvm* | 5495 | F: arch/powerpc/include/asm/kvm* |
5496 | F: arch/powerpc/kvm/ | 5496 | F: arch/powerpc/kvm/ |
5497 | 5497 | ||
5498 | KERNEL VIRTUAL MACHINE For Itanium (KVM/IA64) | ||
5499 | M: Xiantao Zhang <xiantao.zhang@intel.com> | ||
5500 | L: kvm-ia64@vger.kernel.org | ||
5501 | W: http://kvm.qumranet.com | ||
5502 | S: Supported | ||
5503 | F: Documentation/ia64/kvm.txt | ||
5504 | F: arch/ia64/include/asm/kvm* | ||
5505 | F: arch/ia64/kvm/ | ||
5506 | |||
5507 | KERNEL VIRTUAL MACHINE for s390 (KVM/s390) | 5498 | KERNEL VIRTUAL MACHINE for s390 (KVM/s390) |
5508 | M: Christian Borntraeger <borntraeger@de.ibm.com> | 5499 | M: Christian Borntraeger <borntraeger@de.ibm.com> |
5509 | M: Cornelia Huck <cornelia.huck@de.ibm.com> | 5500 | M: Cornelia Huck <cornelia.huck@de.ibm.com> |
diff --git a/arch/arm/include/asm/kvm_emulate.h b/arch/arm/include/asm/kvm_emulate.h index b9db269c6e61..66ce17655bb9 100644 --- a/arch/arm/include/asm/kvm_emulate.h +++ b/arch/arm/include/asm/kvm_emulate.h | |||
@@ -33,6 +33,11 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu); | |||
33 | void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr); | 33 | void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr); |
34 | void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr); | 34 | void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr); |
35 | 35 | ||
36 | static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu) | ||
37 | { | ||
38 | vcpu->arch.hcr = HCR_GUEST_MASK; | ||
39 | } | ||
40 | |||
36 | static inline bool vcpu_mode_is_32bit(struct kvm_vcpu *vcpu) | 41 | static inline bool vcpu_mode_is_32bit(struct kvm_vcpu *vcpu) |
37 | { | 42 | { |
38 | return 1; | 43 | return 1; |
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 53036e21756b..254e0650e48b 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h | |||
@@ -150,8 +150,6 @@ struct kvm_vcpu_stat { | |||
150 | u32 halt_wakeup; | 150 | u32 halt_wakeup; |
151 | }; | 151 | }; |
152 | 152 | ||
153 | int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, | ||
154 | const struct kvm_vcpu_init *init); | ||
155 | int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init); | 153 | int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init); |
156 | unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu); | 154 | unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu); |
157 | int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices); | 155 | int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices); |
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h index acb0d5712716..63e0ecc04901 100644 --- a/arch/arm/include/asm/kvm_mmu.h +++ b/arch/arm/include/asm/kvm_mmu.h | |||
@@ -52,6 +52,7 @@ int create_hyp_io_mappings(void *from, void *to, phys_addr_t); | |||
52 | void free_boot_hyp_pgd(void); | 52 | void free_boot_hyp_pgd(void); |
53 | void free_hyp_pgds(void); | 53 | void free_hyp_pgds(void); |
54 | 54 | ||
55 | void stage2_unmap_vm(struct kvm *kvm); | ||
55 | int kvm_alloc_stage2_pgd(struct kvm *kvm); | 56 | int kvm_alloc_stage2_pgd(struct kvm *kvm); |
56 | void kvm_free_stage2_pgd(struct kvm *kvm); | 57 | void kvm_free_stage2_pgd(struct kvm *kvm); |
57 | int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, | 58 | int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, |
@@ -161,9 +162,10 @@ static inline bool vcpu_has_cache_enabled(struct kvm_vcpu *vcpu) | |||
161 | } | 162 | } |
162 | 163 | ||
163 | static inline void coherent_cache_guest_page(struct kvm_vcpu *vcpu, hva_t hva, | 164 | static inline void coherent_cache_guest_page(struct kvm_vcpu *vcpu, hva_t hva, |
164 | unsigned long size) | 165 | unsigned long size, |
166 | bool ipa_uncached) | ||
165 | { | 167 | { |
166 | if (!vcpu_has_cache_enabled(vcpu)) | 168 | if (!vcpu_has_cache_enabled(vcpu) || ipa_uncached) |
167 | kvm_flush_dcache_to_poc((void *)hva, size); | 169 | kvm_flush_dcache_to_poc((void *)hva, size); |
168 | 170 | ||
169 | /* | 171 | /* |
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 9e193c8a959e..2d6d91001062 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c | |||
@@ -213,6 +213,11 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) | |||
213 | int err; | 213 | int err; |
214 | struct kvm_vcpu *vcpu; | 214 | struct kvm_vcpu *vcpu; |
215 | 215 | ||
216 | if (irqchip_in_kernel(kvm) && vgic_initialized(kvm)) { | ||
217 | err = -EBUSY; | ||
218 | goto out; | ||
219 | } | ||
220 | |||
216 | vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL); | 221 | vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL); |
217 | if (!vcpu) { | 222 | if (!vcpu) { |
218 | err = -ENOMEM; | 223 | err = -ENOMEM; |
@@ -263,6 +268,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | |||
263 | { | 268 | { |
264 | /* Force users to call KVM_ARM_VCPU_INIT */ | 269 | /* Force users to call KVM_ARM_VCPU_INIT */ |
265 | vcpu->arch.target = -1; | 270 | vcpu->arch.target = -1; |
271 | bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES); | ||
266 | 272 | ||
267 | /* Set up the timer */ | 273 | /* Set up the timer */ |
268 | kvm_timer_vcpu_init(vcpu); | 274 | kvm_timer_vcpu_init(vcpu); |
@@ -419,6 +425,7 @@ static void update_vttbr(struct kvm *kvm) | |||
419 | 425 | ||
420 | static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) | 426 | static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) |
421 | { | 427 | { |
428 | struct kvm *kvm = vcpu->kvm; | ||
422 | int ret; | 429 | int ret; |
423 | 430 | ||
424 | if (likely(vcpu->arch.has_run_once)) | 431 | if (likely(vcpu->arch.has_run_once)) |
@@ -427,15 +434,23 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) | |||
427 | vcpu->arch.has_run_once = true; | 434 | vcpu->arch.has_run_once = true; |
428 | 435 | ||
429 | /* | 436 | /* |
430 | * Initialize the VGIC before running a vcpu the first time on | 437 | * Map the VGIC hardware resources before running a vcpu the first |
431 | * this VM. | 438 | * time on this VM. |
432 | */ | 439 | */ |
433 | if (unlikely(!vgic_initialized(vcpu->kvm))) { | 440 | if (unlikely(!vgic_ready(kvm))) { |
434 | ret = kvm_vgic_init(vcpu->kvm); | 441 | ret = kvm_vgic_map_resources(kvm); |
435 | if (ret) | 442 | if (ret) |
436 | return ret; | 443 | return ret; |
437 | } | 444 | } |
438 | 445 | ||
446 | /* | ||
447 | * Enable the arch timers only if we have an in-kernel VGIC | ||
448 | * and it has been properly initialized, since we cannot handle | ||
449 | * interrupts from the virtual timer with a userspace gic. | ||
450 | */ | ||
451 | if (irqchip_in_kernel(kvm) && vgic_initialized(kvm)) | ||
452 | kvm_timer_enable(kvm); | ||
453 | |||
439 | return 0; | 454 | return 0; |
440 | } | 455 | } |
441 | 456 | ||
@@ -649,6 +664,48 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level, | |||
649 | return -EINVAL; | 664 | return -EINVAL; |
650 | } | 665 | } |
651 | 666 | ||
667 | static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, | ||
668 | const struct kvm_vcpu_init *init) | ||
669 | { | ||
670 | unsigned int i; | ||
671 | int phys_target = kvm_target_cpu(); | ||
672 | |||
673 | if (init->target != phys_target) | ||
674 | return -EINVAL; | ||
675 | |||
676 | /* | ||
677 | * Secondary and subsequent calls to KVM_ARM_VCPU_INIT must | ||
678 | * use the same target. | ||
679 | */ | ||
680 | if (vcpu->arch.target != -1 && vcpu->arch.target != init->target) | ||
681 | return -EINVAL; | ||
682 | |||
683 | /* -ENOENT for unknown features, -EINVAL for invalid combinations. */ | ||
684 | for (i = 0; i < sizeof(init->features) * 8; i++) { | ||
685 | bool set = (init->features[i / 32] & (1 << (i % 32))); | ||
686 | |||
687 | if (set && i >= KVM_VCPU_MAX_FEATURES) | ||
688 | return -ENOENT; | ||
689 | |||
690 | /* | ||
691 | * Secondary and subsequent calls to KVM_ARM_VCPU_INIT must | ||
692 | * use the same feature set. | ||
693 | */ | ||
694 | if (vcpu->arch.target != -1 && i < KVM_VCPU_MAX_FEATURES && | ||
695 | test_bit(i, vcpu->arch.features) != set) | ||
696 | return -EINVAL; | ||
697 | |||
698 | if (set) | ||
699 | set_bit(i, vcpu->arch.features); | ||
700 | } | ||
701 | |||
702 | vcpu->arch.target = phys_target; | ||
703 | |||
704 | /* Now we know what it is, we can reset it. */ | ||
705 | return kvm_reset_vcpu(vcpu); | ||
706 | } | ||
707 | |||
708 | |||
652 | static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu, | 709 | static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu, |
653 | struct kvm_vcpu_init *init) | 710 | struct kvm_vcpu_init *init) |
654 | { | 711 | { |
@@ -659,10 +716,21 @@ static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu, | |||
659 | return ret; | 716 | return ret; |
660 | 717 | ||
661 | /* | 718 | /* |
719 | * Ensure a rebooted VM will fault in RAM pages and detect if the | ||
720 | * guest MMU is turned off and flush the caches as needed. | ||
721 | */ | ||
722 | if (vcpu->arch.has_run_once) | ||
723 | stage2_unmap_vm(vcpu->kvm); | ||
724 | |||
725 | vcpu_reset_hcr(vcpu); | ||
726 | |||
727 | /* | ||
662 | * Handle the "start in power-off" case by marking the VCPU as paused. | 728 | * Handle the "start in power-off" case by marking the VCPU as paused. |
663 | */ | 729 | */ |
664 | if (__test_and_clear_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features)) | 730 | if (test_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features)) |
665 | vcpu->arch.pause = true; | 731 | vcpu->arch.pause = true; |
732 | else | ||
733 | vcpu->arch.pause = false; | ||
666 | 734 | ||
667 | return 0; | 735 | return 0; |
668 | } | 736 | } |
diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c index cc0b78769bd8..384bab67c462 100644 --- a/arch/arm/kvm/guest.c +++ b/arch/arm/kvm/guest.c | |||
@@ -38,7 +38,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { | |||
38 | 38 | ||
39 | int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | 39 | int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) |
40 | { | 40 | { |
41 | vcpu->arch.hcr = HCR_GUEST_MASK; | ||
42 | return 0; | 41 | return 0; |
43 | } | 42 | } |
44 | 43 | ||
@@ -274,31 +273,6 @@ int __attribute_const__ kvm_target_cpu(void) | |||
274 | } | 273 | } |
275 | } | 274 | } |
276 | 275 | ||
277 | int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, | ||
278 | const struct kvm_vcpu_init *init) | ||
279 | { | ||
280 | unsigned int i; | ||
281 | |||
282 | /* We can only cope with guest==host and only on A15/A7 (for now). */ | ||
283 | if (init->target != kvm_target_cpu()) | ||
284 | return -EINVAL; | ||
285 | |||
286 | vcpu->arch.target = init->target; | ||
287 | bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES); | ||
288 | |||
289 | /* -ENOENT for unknown features, -EINVAL for invalid combinations. */ | ||
290 | for (i = 0; i < sizeof(init->features) * 8; i++) { | ||
291 | if (test_bit(i, (void *)init->features)) { | ||
292 | if (i >= KVM_VCPU_MAX_FEATURES) | ||
293 | return -ENOENT; | ||
294 | set_bit(i, vcpu->arch.features); | ||
295 | } | ||
296 | } | ||
297 | |||
298 | /* Now we know what it is, we can reset it. */ | ||
299 | return kvm_reset_vcpu(vcpu); | ||
300 | } | ||
301 | |||
302 | int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init) | 276 | int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init) |
303 | { | 277 | { |
304 | int target = kvm_target_cpu(); | 278 | int target = kvm_target_cpu(); |
diff --git a/arch/arm/kvm/mmio.c b/arch/arm/kvm/mmio.c index 4cb5a93182e9..5d3bfc0eb3f0 100644 --- a/arch/arm/kvm/mmio.c +++ b/arch/arm/kvm/mmio.c | |||
@@ -187,15 +187,18 @@ int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, | |||
187 | } | 187 | } |
188 | 188 | ||
189 | rt = vcpu->arch.mmio_decode.rt; | 189 | rt = vcpu->arch.mmio_decode.rt; |
190 | data = vcpu_data_guest_to_host(vcpu, *vcpu_reg(vcpu, rt), mmio.len); | ||
191 | 190 | ||
192 | trace_kvm_mmio((mmio.is_write) ? KVM_TRACE_MMIO_WRITE : | 191 | if (mmio.is_write) { |
193 | KVM_TRACE_MMIO_READ_UNSATISFIED, | 192 | data = vcpu_data_guest_to_host(vcpu, *vcpu_reg(vcpu, rt), |
194 | mmio.len, fault_ipa, | 193 | mmio.len); |
195 | (mmio.is_write) ? data : 0); | ||
196 | 194 | ||
197 | if (mmio.is_write) | 195 | trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, mmio.len, |
196 | fault_ipa, data); | ||
198 | mmio_write_buf(mmio.data, mmio.len, data); | 197 | mmio_write_buf(mmio.data, mmio.len, data); |
198 | } else { | ||
199 | trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, mmio.len, | ||
200 | fault_ipa, 0); | ||
201 | } | ||
199 | 202 | ||
200 | if (vgic_handle_mmio(vcpu, run, &mmio)) | 203 | if (vgic_handle_mmio(vcpu, run, &mmio)) |
201 | return 1; | 204 | return 1; |
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 8664ff17cbbe..1dc9778a00af 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c | |||
@@ -612,6 +612,71 @@ static void unmap_stage2_range(struct kvm *kvm, phys_addr_t start, u64 size) | |||
612 | unmap_range(kvm, kvm->arch.pgd, start, size); | 612 | unmap_range(kvm, kvm->arch.pgd, start, size); |
613 | } | 613 | } |
614 | 614 | ||
615 | static void stage2_unmap_memslot(struct kvm *kvm, | ||
616 | struct kvm_memory_slot *memslot) | ||
617 | { | ||
618 | hva_t hva = memslot->userspace_addr; | ||
619 | phys_addr_t addr = memslot->base_gfn << PAGE_SHIFT; | ||
620 | phys_addr_t size = PAGE_SIZE * memslot->npages; | ||
621 | hva_t reg_end = hva + size; | ||
622 | |||
623 | /* | ||
624 | * A memory region could potentially cover multiple VMAs, and any holes | ||
625 | * between them, so iterate over all of them to find out if we should | ||
626 | * unmap any of them. | ||
627 | * | ||
628 | * +--------------------------------------------+ | ||
629 | * +---------------+----------------+ +----------------+ | ||
630 | * | : VMA 1 | VMA 2 | | VMA 3 : | | ||
631 | * +---------------+----------------+ +----------------+ | ||
632 | * | memory region | | ||
633 | * +--------------------------------------------+ | ||
634 | */ | ||
635 | do { | ||
636 | struct vm_area_struct *vma = find_vma(current->mm, hva); | ||
637 | hva_t vm_start, vm_end; | ||
638 | |||
639 | if (!vma || vma->vm_start >= reg_end) | ||
640 | break; | ||
641 | |||
642 | /* | ||
643 | * Take the intersection of this VMA with the memory region | ||
644 | */ | ||
645 | vm_start = max(hva, vma->vm_start); | ||
646 | vm_end = min(reg_end, vma->vm_end); | ||
647 | |||
648 | if (!(vma->vm_flags & VM_PFNMAP)) { | ||
649 | gpa_t gpa = addr + (vm_start - memslot->userspace_addr); | ||
650 | unmap_stage2_range(kvm, gpa, vm_end - vm_start); | ||
651 | } | ||
652 | hva = vm_end; | ||
653 | } while (hva < reg_end); | ||
654 | } | ||
655 | |||
656 | /** | ||
657 | * stage2_unmap_vm - Unmap Stage-2 RAM mappings | ||
658 | * @kvm: The struct kvm pointer | ||
659 | * | ||
660 | * Go through the memregions and unmap any reguler RAM | ||
661 | * backing memory already mapped to the VM. | ||
662 | */ | ||
663 | void stage2_unmap_vm(struct kvm *kvm) | ||
664 | { | ||
665 | struct kvm_memslots *slots; | ||
666 | struct kvm_memory_slot *memslot; | ||
667 | int idx; | ||
668 | |||
669 | idx = srcu_read_lock(&kvm->srcu); | ||
670 | spin_lock(&kvm->mmu_lock); | ||
671 | |||
672 | slots = kvm_memslots(kvm); | ||
673 | kvm_for_each_memslot(memslot, slots) | ||
674 | stage2_unmap_memslot(kvm, memslot); | ||
675 | |||
676 | spin_unlock(&kvm->mmu_lock); | ||
677 | srcu_read_unlock(&kvm->srcu, idx); | ||
678 | } | ||
679 | |||
615 | /** | 680 | /** |
616 | * kvm_free_stage2_pgd - free all stage-2 tables | 681 | * kvm_free_stage2_pgd - free all stage-2 tables |
617 | * @kvm: The KVM struct pointer for the VM. | 682 | * @kvm: The KVM struct pointer for the VM. |
@@ -853,6 +918,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
853 | struct vm_area_struct *vma; | 918 | struct vm_area_struct *vma; |
854 | pfn_t pfn; | 919 | pfn_t pfn; |
855 | pgprot_t mem_type = PAGE_S2; | 920 | pgprot_t mem_type = PAGE_S2; |
921 | bool fault_ipa_uncached; | ||
856 | 922 | ||
857 | write_fault = kvm_is_write_fault(vcpu); | 923 | write_fault = kvm_is_write_fault(vcpu); |
858 | if (fault_status == FSC_PERM && !write_fault) { | 924 | if (fault_status == FSC_PERM && !write_fault) { |
@@ -919,6 +985,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
919 | if (!hugetlb && !force_pte) | 985 | if (!hugetlb && !force_pte) |
920 | hugetlb = transparent_hugepage_adjust(&pfn, &fault_ipa); | 986 | hugetlb = transparent_hugepage_adjust(&pfn, &fault_ipa); |
921 | 987 | ||
988 | fault_ipa_uncached = memslot->flags & KVM_MEMSLOT_INCOHERENT; | ||
989 | |||
922 | if (hugetlb) { | 990 | if (hugetlb) { |
923 | pmd_t new_pmd = pfn_pmd(pfn, mem_type); | 991 | pmd_t new_pmd = pfn_pmd(pfn, mem_type); |
924 | new_pmd = pmd_mkhuge(new_pmd); | 992 | new_pmd = pmd_mkhuge(new_pmd); |
@@ -926,7 +994,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
926 | kvm_set_s2pmd_writable(&new_pmd); | 994 | kvm_set_s2pmd_writable(&new_pmd); |
927 | kvm_set_pfn_dirty(pfn); | 995 | kvm_set_pfn_dirty(pfn); |
928 | } | 996 | } |
929 | coherent_cache_guest_page(vcpu, hva & PMD_MASK, PMD_SIZE); | 997 | coherent_cache_guest_page(vcpu, hva & PMD_MASK, PMD_SIZE, |
998 | fault_ipa_uncached); | ||
930 | ret = stage2_set_pmd_huge(kvm, memcache, fault_ipa, &new_pmd); | 999 | ret = stage2_set_pmd_huge(kvm, memcache, fault_ipa, &new_pmd); |
931 | } else { | 1000 | } else { |
932 | pte_t new_pte = pfn_pte(pfn, mem_type); | 1001 | pte_t new_pte = pfn_pte(pfn, mem_type); |
@@ -934,7 +1003,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
934 | kvm_set_s2pte_writable(&new_pte); | 1003 | kvm_set_s2pte_writable(&new_pte); |
935 | kvm_set_pfn_dirty(pfn); | 1004 | kvm_set_pfn_dirty(pfn); |
936 | } | 1005 | } |
937 | coherent_cache_guest_page(vcpu, hva, PAGE_SIZE); | 1006 | coherent_cache_guest_page(vcpu, hva, PAGE_SIZE, |
1007 | fault_ipa_uncached); | ||
938 | ret = stage2_set_pte(kvm, memcache, fault_ipa, &new_pte, | 1008 | ret = stage2_set_pte(kvm, memcache, fault_ipa, &new_pte, |
939 | pgprot_val(mem_type) == pgprot_val(PAGE_S2_DEVICE)); | 1009 | pgprot_val(mem_type) == pgprot_val(PAGE_S2_DEVICE)); |
940 | } | 1010 | } |
@@ -1294,11 +1364,12 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, | |||
1294 | hva = vm_end; | 1364 | hva = vm_end; |
1295 | } while (hva < reg_end); | 1365 | } while (hva < reg_end); |
1296 | 1366 | ||
1297 | if (ret) { | 1367 | spin_lock(&kvm->mmu_lock); |
1298 | spin_lock(&kvm->mmu_lock); | 1368 | if (ret) |
1299 | unmap_stage2_range(kvm, mem->guest_phys_addr, mem->memory_size); | 1369 | unmap_stage2_range(kvm, mem->guest_phys_addr, mem->memory_size); |
1300 | spin_unlock(&kvm->mmu_lock); | 1370 | else |
1301 | } | 1371 | stage2_flush_memslot(kvm, memslot); |
1372 | spin_unlock(&kvm->mmu_lock); | ||
1302 | return ret; | 1373 | return ret; |
1303 | } | 1374 | } |
1304 | 1375 | ||
@@ -1310,6 +1381,15 @@ void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, | |||
1310 | int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, | 1381 | int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, |
1311 | unsigned long npages) | 1382 | unsigned long npages) |
1312 | { | 1383 | { |
1384 | /* | ||
1385 | * Readonly memslots are not incoherent with the caches by definition, | ||
1386 | * but in practice, they are used mostly to emulate ROMs or NOR flashes | ||
1387 | * that the guest may consider devices and hence map as uncached. | ||
1388 | * To prevent incoherency issues in these cases, tag all readonly | ||
1389 | * regions as incoherent. | ||
1390 | */ | ||
1391 | if (slot->flags & KVM_MEM_READONLY) | ||
1392 | slot->flags |= KVM_MEMSLOT_INCOHERENT; | ||
1313 | return 0; | 1393 | return 0; |
1314 | } | 1394 | } |
1315 | 1395 | ||
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c index 09cf37737ee2..58cb3248d277 100644 --- a/arch/arm/kvm/psci.c +++ b/arch/arm/kvm/psci.c | |||
@@ -15,6 +15,7 @@ | |||
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/preempt.h> | ||
18 | #include <linux/kvm_host.h> | 19 | #include <linux/kvm_host.h> |
19 | #include <linux/wait.h> | 20 | #include <linux/wait.h> |
20 | 21 | ||
@@ -166,6 +167,23 @@ static unsigned long kvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu) | |||
166 | 167 | ||
167 | static void kvm_prepare_system_event(struct kvm_vcpu *vcpu, u32 type) | 168 | static void kvm_prepare_system_event(struct kvm_vcpu *vcpu, u32 type) |
168 | { | 169 | { |
170 | int i; | ||
171 | struct kvm_vcpu *tmp; | ||
172 | |||
173 | /* | ||
174 | * The KVM ABI specifies that a system event exit may call KVM_RUN | ||
175 | * again and may perform shutdown/reboot at a later time that when the | ||
176 | * actual request is made. Since we are implementing PSCI and a | ||
177 | * caller of PSCI reboot and shutdown expects that the system shuts | ||
178 | * down or reboots immediately, let's make sure that VCPUs are not run | ||
179 | * after this call is handled and before the VCPUs have been | ||
180 | * re-initialized. | ||
181 | */ | ||
182 | kvm_for_each_vcpu(i, tmp, vcpu->kvm) { | ||
183 | tmp->arch.pause = true; | ||
184 | kvm_vcpu_kick(tmp); | ||
185 | } | ||
186 | |||
169 | memset(&vcpu->run->system_event, 0, sizeof(vcpu->run->system_event)); | 187 | memset(&vcpu->run->system_event, 0, sizeof(vcpu->run->system_event)); |
170 | vcpu->run->system_event.type = type; | 188 | vcpu->run->system_event.type = type; |
171 | vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT; | 189 | vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT; |
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index 5674a55b5518..8127e45e2637 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h | |||
@@ -38,6 +38,11 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu); | |||
38 | void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr); | 38 | void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr); |
39 | void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr); | 39 | void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr); |
40 | 40 | ||
41 | static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu) | ||
42 | { | ||
43 | vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS; | ||
44 | } | ||
45 | |||
41 | static inline unsigned long *vcpu_pc(const struct kvm_vcpu *vcpu) | 46 | static inline unsigned long *vcpu_pc(const struct kvm_vcpu *vcpu) |
42 | { | 47 | { |
43 | return (unsigned long *)&vcpu_gp_regs(vcpu)->regs.pc; | 48 | return (unsigned long *)&vcpu_gp_regs(vcpu)->regs.pc; |
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 2012c4ba8d67..0b7dfdb931df 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h | |||
@@ -165,8 +165,6 @@ struct kvm_vcpu_stat { | |||
165 | u32 halt_wakeup; | 165 | u32 halt_wakeup; |
166 | }; | 166 | }; |
167 | 167 | ||
168 | int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, | ||
169 | const struct kvm_vcpu_init *init); | ||
170 | int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init); | 168 | int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init); |
171 | unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu); | 169 | unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu); |
172 | int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices); | 170 | int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices); |
@@ -200,6 +198,7 @@ struct kvm_vcpu *kvm_arm_get_running_vcpu(void); | |||
200 | struct kvm_vcpu * __percpu *kvm_get_running_vcpus(void); | 198 | struct kvm_vcpu * __percpu *kvm_get_running_vcpus(void); |
201 | 199 | ||
202 | u64 kvm_call_hyp(void *hypfn, ...); | 200 | u64 kvm_call_hyp(void *hypfn, ...); |
201 | void force_vm_exit(const cpumask_t *mask); | ||
203 | 202 | ||
204 | int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, | 203 | int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, |
205 | int exception_index); | 204 | int exception_index); |
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h index 0caf7a59f6a1..14a74f136272 100644 --- a/arch/arm64/include/asm/kvm_mmu.h +++ b/arch/arm64/include/asm/kvm_mmu.h | |||
@@ -83,6 +83,7 @@ int create_hyp_io_mappings(void *from, void *to, phys_addr_t); | |||
83 | void free_boot_hyp_pgd(void); | 83 | void free_boot_hyp_pgd(void); |
84 | void free_hyp_pgds(void); | 84 | void free_hyp_pgds(void); |
85 | 85 | ||
86 | void stage2_unmap_vm(struct kvm *kvm); | ||
86 | int kvm_alloc_stage2_pgd(struct kvm *kvm); | 87 | int kvm_alloc_stage2_pgd(struct kvm *kvm); |
87 | void kvm_free_stage2_pgd(struct kvm *kvm); | 88 | void kvm_free_stage2_pgd(struct kvm *kvm); |
88 | int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, | 89 | int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, |
@@ -243,9 +244,10 @@ static inline bool vcpu_has_cache_enabled(struct kvm_vcpu *vcpu) | |||
243 | } | 244 | } |
244 | 245 | ||
245 | static inline void coherent_cache_guest_page(struct kvm_vcpu *vcpu, hva_t hva, | 246 | static inline void coherent_cache_guest_page(struct kvm_vcpu *vcpu, hva_t hva, |
246 | unsigned long size) | 247 | unsigned long size, |
248 | bool ipa_uncached) | ||
247 | { | 249 | { |
248 | if (!vcpu_has_cache_enabled(vcpu)) | 250 | if (!vcpu_has_cache_enabled(vcpu) || ipa_uncached) |
249 | kvm_flush_dcache_to_poc((void *)hva, size); | 251 | kvm_flush_dcache_to_poc((void *)hva, size); |
250 | 252 | ||
251 | if (!icache_is_aliasing()) { /* PIPT */ | 253 | if (!icache_is_aliasing()) { /* PIPT */ |
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c index 76794692c20b..9535bd555d1d 100644 --- a/arch/arm64/kvm/guest.c +++ b/arch/arm64/kvm/guest.c | |||
@@ -38,7 +38,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { | |||
38 | 38 | ||
39 | int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | 39 | int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) |
40 | { | 40 | { |
41 | vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS; | ||
42 | return 0; | 41 | return 0; |
43 | } | 42 | } |
44 | 43 | ||
@@ -297,31 +296,6 @@ int __attribute_const__ kvm_target_cpu(void) | |||
297 | return -EINVAL; | 296 | return -EINVAL; |
298 | } | 297 | } |
299 | 298 | ||
300 | int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, | ||
301 | const struct kvm_vcpu_init *init) | ||
302 | { | ||
303 | unsigned int i; | ||
304 | int phys_target = kvm_target_cpu(); | ||
305 | |||
306 | if (init->target != phys_target) | ||
307 | return -EINVAL; | ||
308 | |||
309 | vcpu->arch.target = phys_target; | ||
310 | bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES); | ||
311 | |||
312 | /* -ENOENT for unknown features, -EINVAL for invalid combinations. */ | ||
313 | for (i = 0; i < sizeof(init->features) * 8; i++) { | ||
314 | if (init->features[i / 32] & (1 << (i % 32))) { | ||
315 | if (i >= KVM_VCPU_MAX_FEATURES) | ||
316 | return -ENOENT; | ||
317 | set_bit(i, vcpu->arch.features); | ||
318 | } | ||
319 | } | ||
320 | |||
321 | /* Now we know what it is, we can reset it. */ | ||
322 | return kvm_reset_vcpu(vcpu); | ||
323 | } | ||
324 | |||
325 | int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init) | 299 | int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init) |
326 | { | 300 | { |
327 | int target = kvm_target_cpu(); | 301 | int target = kvm_target_cpu(); |
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 536d13b0bea6..371b55bc5a6e 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
@@ -20,7 +20,6 @@ config IA64 | |||
20 | select HAVE_DYNAMIC_FTRACE if (!ITANIUM) | 20 | select HAVE_DYNAMIC_FTRACE if (!ITANIUM) |
21 | select HAVE_FUNCTION_TRACER | 21 | select HAVE_FUNCTION_TRACER |
22 | select HAVE_DMA_ATTRS | 22 | select HAVE_DMA_ATTRS |
23 | select HAVE_KVM | ||
24 | select TTY | 23 | select TTY |
25 | select HAVE_ARCH_TRACEHOOK | 24 | select HAVE_ARCH_TRACEHOOK |
26 | select HAVE_DMA_API_DEBUG | 25 | select HAVE_DMA_API_DEBUG |
@@ -640,8 +639,6 @@ source "security/Kconfig" | |||
640 | 639 | ||
641 | source "crypto/Kconfig" | 640 | source "crypto/Kconfig" |
642 | 641 | ||
643 | source "arch/ia64/kvm/Kconfig" | ||
644 | |||
645 | source "lib/Kconfig" | 642 | source "lib/Kconfig" |
646 | 643 | ||
647 | config IOMMU_HELPER | 644 | config IOMMU_HELPER |
diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index 5441b14994fc..970d0bd99621 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile | |||
@@ -53,7 +53,6 @@ core-$(CONFIG_IA64_HP_ZX1) += arch/ia64/dig/ | |||
53 | core-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/dig/ | 53 | core-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/dig/ |
54 | core-$(CONFIG_IA64_SGI_SN2) += arch/ia64/sn/ | 54 | core-$(CONFIG_IA64_SGI_SN2) += arch/ia64/sn/ |
55 | core-$(CONFIG_IA64_SGI_UV) += arch/ia64/uv/ | 55 | core-$(CONFIG_IA64_SGI_UV) += arch/ia64/uv/ |
56 | core-$(CONFIG_KVM) += arch/ia64/kvm/ | ||
57 | 56 | ||
58 | drivers-$(CONFIG_PCI) += arch/ia64/pci/ | 57 | drivers-$(CONFIG_PCI) += arch/ia64/pci/ |
59 | drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/ | 58 | drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/ |
diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h deleted file mode 100644 index 4729752b7256..000000000000 --- a/arch/ia64/include/asm/kvm_host.h +++ /dev/null | |||
@@ -1,609 +0,0 @@ | |||
1 | /* | ||
2 | * kvm_host.h: used for kvm module, and hold ia64-specific sections. | ||
3 | * | ||
4 | * Copyright (C) 2007, Intel Corporation. | ||
5 | * | ||
6 | * Xiantao Zhang <xiantao.zhang@intel.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms and conditions of the GNU General Public License, | ||
10 | * version 2, as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along with | ||
18 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | ||
19 | * Place - Suite 330, Boston, MA 02111-1307 USA. | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #ifndef __ASM_KVM_HOST_H | ||
24 | #define __ASM_KVM_HOST_H | ||
25 | |||
26 | #define KVM_USER_MEM_SLOTS 32 | ||
27 | |||
28 | #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 | ||
29 | #define KVM_IRQCHIP_NUM_PINS KVM_IOAPIC_NUM_PINS | ||
30 | |||
31 | /* define exit reasons from vmm to kvm*/ | ||
32 | #define EXIT_REASON_VM_PANIC 0 | ||
33 | #define EXIT_REASON_MMIO_INSTRUCTION 1 | ||
34 | #define EXIT_REASON_PAL_CALL 2 | ||
35 | #define EXIT_REASON_SAL_CALL 3 | ||
36 | #define EXIT_REASON_SWITCH_RR6 4 | ||
37 | #define EXIT_REASON_VM_DESTROY 5 | ||
38 | #define EXIT_REASON_EXTERNAL_INTERRUPT 6 | ||
39 | #define EXIT_REASON_IPI 7 | ||
40 | #define EXIT_REASON_PTC_G 8 | ||
41 | #define EXIT_REASON_DEBUG 20 | ||
42 | |||
43 | /*Define vmm address space and vm data space.*/ | ||
44 | #define KVM_VMM_SIZE (__IA64_UL_CONST(16)<<20) | ||
45 | #define KVM_VMM_SHIFT 24 | ||
46 | #define KVM_VMM_BASE 0xD000000000000000 | ||
47 | #define VMM_SIZE (__IA64_UL_CONST(8)<<20) | ||
48 | |||
49 | /* | ||
50 | * Define vm_buffer, used by PAL Services, base address. | ||
51 | * Note: vm_buffer is in the VMM-BLOCK, the size must be < 8M | ||
52 | */ | ||
53 | #define KVM_VM_BUFFER_BASE (KVM_VMM_BASE + VMM_SIZE) | ||
54 | #define KVM_VM_BUFFER_SIZE (__IA64_UL_CONST(8)<<20) | ||
55 | |||
56 | /* | ||
57 | * kvm guest's data area looks as follow: | ||
58 | * | ||
59 | * +----------------------+ ------- KVM_VM_DATA_SIZE | ||
60 | * | vcpu[n]'s data | | ___________________KVM_STK_OFFSET | ||
61 | * | | | / | | ||
62 | * | .......... | | /vcpu's struct&stack | | ||
63 | * | .......... | | /---------------------|---- 0 | ||
64 | * | vcpu[5]'s data | | / vpd | | ||
65 | * | vcpu[4]'s data | |/-----------------------| | ||
66 | * | vcpu[3]'s data | / vtlb | | ||
67 | * | vcpu[2]'s data | /|------------------------| | ||
68 | * | vcpu[1]'s data |/ | vhpt | | ||
69 | * | vcpu[0]'s data |____________________________| | ||
70 | * +----------------------+ | | ||
71 | * | memory dirty log | | | ||
72 | * +----------------------+ | | ||
73 | * | vm's data struct | | | ||
74 | * +----------------------+ | | ||
75 | * | | | | ||
76 | * | | | | ||
77 | * | | | | ||
78 | * | | | | ||
79 | * | | | | ||
80 | * | | | | ||
81 | * | | | | ||
82 | * | vm's p2m table | | | ||
83 | * | | | | ||
84 | * | | | | ||
85 | * | | | | | ||
86 | * vm's data->| | | | | ||
87 | * +----------------------+ ------- 0 | ||
88 | * To support large memory, needs to increase the size of p2m. | ||
89 | * To support more vcpus, needs to ensure it has enough space to | ||
90 | * hold vcpus' data. | ||
91 | */ | ||
92 | |||
93 | #define KVM_VM_DATA_SHIFT 26 | ||
94 | #define KVM_VM_DATA_SIZE (__IA64_UL_CONST(1) << KVM_VM_DATA_SHIFT) | ||
95 | #define KVM_VM_DATA_BASE (KVM_VMM_BASE + KVM_VM_DATA_SIZE) | ||
96 | |||
97 | #define KVM_P2M_BASE KVM_VM_DATA_BASE | ||
98 | #define KVM_P2M_SIZE (__IA64_UL_CONST(24) << 20) | ||
99 | |||
100 | #define VHPT_SHIFT 16 | ||
101 | #define VHPT_SIZE (__IA64_UL_CONST(1) << VHPT_SHIFT) | ||
102 | #define VHPT_NUM_ENTRIES (__IA64_UL_CONST(1) << (VHPT_SHIFT-5)) | ||
103 | |||
104 | #define VTLB_SHIFT 16 | ||
105 | #define VTLB_SIZE (__IA64_UL_CONST(1) << VTLB_SHIFT) | ||
106 | #define VTLB_NUM_ENTRIES (1UL << (VHPT_SHIFT-5)) | ||
107 | |||
108 | #define VPD_SHIFT 16 | ||
109 | #define VPD_SIZE (__IA64_UL_CONST(1) << VPD_SHIFT) | ||
110 | |||
111 | #define VCPU_STRUCT_SHIFT 16 | ||
112 | #define VCPU_STRUCT_SIZE (__IA64_UL_CONST(1) << VCPU_STRUCT_SHIFT) | ||
113 | |||
114 | /* | ||
115 | * This must match KVM_IA64_VCPU_STACK_{SHIFT,SIZE} arch/ia64/include/asm/kvm.h | ||
116 | */ | ||
117 | #define KVM_STK_SHIFT 16 | ||
118 | #define KVM_STK_OFFSET (__IA64_UL_CONST(1)<< KVM_STK_SHIFT) | ||
119 | |||
120 | #define KVM_VM_STRUCT_SHIFT 19 | ||
121 | #define KVM_VM_STRUCT_SIZE (__IA64_UL_CONST(1) << KVM_VM_STRUCT_SHIFT) | ||
122 | |||
123 | #define KVM_MEM_DIRY_LOG_SHIFT 19 | ||
124 | #define KVM_MEM_DIRTY_LOG_SIZE (__IA64_UL_CONST(1) << KVM_MEM_DIRY_LOG_SHIFT) | ||
125 | |||
126 | #ifndef __ASSEMBLY__ | ||
127 | |||
128 | /*Define the max vcpus and memory for Guests.*/ | ||
129 | #define KVM_MAX_VCPUS (KVM_VM_DATA_SIZE - KVM_P2M_SIZE - KVM_VM_STRUCT_SIZE -\ | ||
130 | KVM_MEM_DIRTY_LOG_SIZE) / sizeof(struct kvm_vcpu_data) | ||
131 | #define KVM_MAX_MEM_SIZE (KVM_P2M_SIZE >> 3 << PAGE_SHIFT) | ||
132 | |||
133 | #define VMM_LOG_LEN 256 | ||
134 | |||
135 | #include <linux/types.h> | ||
136 | #include <linux/mm.h> | ||
137 | #include <linux/kvm.h> | ||
138 | #include <linux/kvm_para.h> | ||
139 | #include <linux/kvm_types.h> | ||
140 | |||
141 | #include <asm/pal.h> | ||
142 | #include <asm/sal.h> | ||
143 | #include <asm/page.h> | ||
144 | |||
145 | struct kvm_vcpu_data { | ||
146 | char vcpu_vhpt[VHPT_SIZE]; | ||
147 | char vcpu_vtlb[VTLB_SIZE]; | ||
148 | char vcpu_vpd[VPD_SIZE]; | ||
149 | char vcpu_struct[VCPU_STRUCT_SIZE]; | ||
150 | }; | ||
151 | |||
152 | struct kvm_vm_data { | ||
153 | char kvm_p2m[KVM_P2M_SIZE]; | ||
154 | char kvm_vm_struct[KVM_VM_STRUCT_SIZE]; | ||
155 | char kvm_mem_dirty_log[KVM_MEM_DIRTY_LOG_SIZE]; | ||
156 | struct kvm_vcpu_data vcpu_data[KVM_MAX_VCPUS]; | ||
157 | }; | ||
158 | |||
159 | #define VCPU_BASE(n) (KVM_VM_DATA_BASE + \ | ||
160 | offsetof(struct kvm_vm_data, vcpu_data[n])) | ||
161 | #define KVM_VM_BASE (KVM_VM_DATA_BASE + \ | ||
162 | offsetof(struct kvm_vm_data, kvm_vm_struct)) | ||
163 | #define KVM_MEM_DIRTY_LOG_BASE KVM_VM_DATA_BASE + \ | ||
164 | offsetof(struct kvm_vm_data, kvm_mem_dirty_log) | ||
165 | |||
166 | #define VHPT_BASE(n) (VCPU_BASE(n) + offsetof(struct kvm_vcpu_data, vcpu_vhpt)) | ||
167 | #define VTLB_BASE(n) (VCPU_BASE(n) + offsetof(struct kvm_vcpu_data, vcpu_vtlb)) | ||
168 | #define VPD_BASE(n) (VCPU_BASE(n) + offsetof(struct kvm_vcpu_data, vcpu_vpd)) | ||
169 | #define VCPU_STRUCT_BASE(n) (VCPU_BASE(n) + \ | ||
170 | offsetof(struct kvm_vcpu_data, vcpu_struct)) | ||
171 | |||
172 | /*IO section definitions*/ | ||
173 | #define IOREQ_READ 1 | ||
174 | #define IOREQ_WRITE 0 | ||
175 | |||
176 | #define STATE_IOREQ_NONE 0 | ||
177 | #define STATE_IOREQ_READY 1 | ||
178 | #define STATE_IOREQ_INPROCESS 2 | ||
179 | #define STATE_IORESP_READY 3 | ||
180 | |||
181 | /*Guest Physical address layout.*/ | ||
182 | #define GPFN_MEM (0UL << 60) /* Guest pfn is normal mem */ | ||
183 | #define GPFN_FRAME_BUFFER (1UL << 60) /* VGA framebuffer */ | ||
184 | #define GPFN_LOW_MMIO (2UL << 60) /* Low MMIO range */ | ||
185 | #define GPFN_PIB (3UL << 60) /* PIB base */ | ||
186 | #define GPFN_IOSAPIC (4UL << 60) /* IOSAPIC base */ | ||
187 | #define GPFN_LEGACY_IO (5UL << 60) /* Legacy I/O base */ | ||
188 | #define GPFN_GFW (6UL << 60) /* Guest Firmware */ | ||
189 | #define GPFN_PHYS_MMIO (7UL << 60) /* Directed MMIO Range */ | ||
190 | |||
191 | #define GPFN_IO_MASK (7UL << 60) /* Guest pfn is I/O type */ | ||
192 | #define GPFN_INV_MASK (1UL << 63) /* Guest pfn is invalid */ | ||
193 | #define INVALID_MFN (~0UL) | ||
194 | #define MEM_G (1UL << 30) | ||
195 | #define MEM_M (1UL << 20) | ||
196 | #define MMIO_START (3 * MEM_G) | ||
197 | #define MMIO_SIZE (512 * MEM_M) | ||
198 | #define VGA_IO_START 0xA0000UL | ||
199 | #define VGA_IO_SIZE 0x20000 | ||
200 | #define LEGACY_IO_START (MMIO_START + MMIO_SIZE) | ||
201 | #define LEGACY_IO_SIZE (64 * MEM_M) | ||
202 | #define IO_SAPIC_START 0xfec00000UL | ||
203 | #define IO_SAPIC_SIZE 0x100000 | ||
204 | #define PIB_START 0xfee00000UL | ||
205 | #define PIB_SIZE 0x200000 | ||
206 | #define GFW_START (4 * MEM_G - 16 * MEM_M) | ||
207 | #define GFW_SIZE (16 * MEM_M) | ||
208 | |||
209 | /*Deliver mode, defined for ioapic.c*/ | ||
210 | #define dest_Fixed IOSAPIC_FIXED | ||
211 | #define dest_LowestPrio IOSAPIC_LOWEST_PRIORITY | ||
212 | |||
213 | #define NMI_VECTOR 2 | ||
214 | #define ExtINT_VECTOR 0 | ||
215 | #define NULL_VECTOR (-1) | ||
216 | #define IA64_SPURIOUS_INT_VECTOR 0x0f | ||
217 | |||
218 | #define VCPU_LID(v) (((u64)(v)->vcpu_id) << 24) | ||
219 | |||
220 | /* | ||
221 | *Delivery mode | ||
222 | */ | ||
223 | #define SAPIC_DELIV_SHIFT 8 | ||
224 | #define SAPIC_FIXED 0x0 | ||
225 | #define SAPIC_LOWEST_PRIORITY 0x1 | ||
226 | #define SAPIC_PMI 0x2 | ||
227 | #define SAPIC_NMI 0x4 | ||
228 | #define SAPIC_INIT 0x5 | ||
229 | #define SAPIC_EXTINT 0x7 | ||
230 | |||
231 | /* | ||
232 | * vcpu->requests bit members for arch | ||
233 | */ | ||
234 | #define KVM_REQ_PTC_G 32 | ||
235 | #define KVM_REQ_RESUME 33 | ||
236 | |||
237 | struct kvm_mmio_req { | ||
238 | uint64_t addr; /* physical address */ | ||
239 | uint64_t size; /* size in bytes */ | ||
240 | uint64_t data; /* data (or paddr of data) */ | ||
241 | uint8_t state:4; | ||
242 | uint8_t dir:1; /* 1=read, 0=write */ | ||
243 | }; | ||
244 | |||
245 | /*Pal data struct */ | ||
246 | struct kvm_pal_call{ | ||
247 | /*In area*/ | ||
248 | uint64_t gr28; | ||
249 | uint64_t gr29; | ||
250 | uint64_t gr30; | ||
251 | uint64_t gr31; | ||
252 | /*Out area*/ | ||
253 | struct ia64_pal_retval ret; | ||
254 | }; | ||
255 | |||
256 | /* Sal data structure */ | ||
257 | struct kvm_sal_call{ | ||
258 | /*In area*/ | ||
259 | uint64_t in0; | ||
260 | uint64_t in1; | ||
261 | uint64_t in2; | ||
262 | uint64_t in3; | ||
263 | uint64_t in4; | ||
264 | uint64_t in5; | ||
265 | uint64_t in6; | ||
266 | uint64_t in7; | ||
267 | struct sal_ret_values ret; | ||
268 | }; | ||
269 | |||
270 | /*Guest change rr6*/ | ||
271 | struct kvm_switch_rr6 { | ||
272 | uint64_t old_rr; | ||
273 | uint64_t new_rr; | ||
274 | }; | ||
275 | |||
276 | union ia64_ipi_a{ | ||
277 | unsigned long val; | ||
278 | struct { | ||
279 | unsigned long rv : 3; | ||
280 | unsigned long ir : 1; | ||
281 | unsigned long eid : 8; | ||
282 | unsigned long id : 8; | ||
283 | unsigned long ib_base : 44; | ||
284 | }; | ||
285 | }; | ||
286 | |||
287 | union ia64_ipi_d { | ||
288 | unsigned long val; | ||
289 | struct { | ||
290 | unsigned long vector : 8; | ||
291 | unsigned long dm : 3; | ||
292 | unsigned long ig : 53; | ||
293 | }; | ||
294 | }; | ||
295 | |||
296 | /*ipi check exit data*/ | ||
297 | struct kvm_ipi_data{ | ||
298 | union ia64_ipi_a addr; | ||
299 | union ia64_ipi_d data; | ||
300 | }; | ||
301 | |||
302 | /*global purge data*/ | ||
303 | struct kvm_ptc_g { | ||
304 | unsigned long vaddr; | ||
305 | unsigned long rr; | ||
306 | unsigned long ps; | ||
307 | struct kvm_vcpu *vcpu; | ||
308 | }; | ||
309 | |||
310 | /*Exit control data */ | ||
311 | struct exit_ctl_data{ | ||
312 | uint32_t exit_reason; | ||
313 | uint32_t vm_status; | ||
314 | union { | ||
315 | struct kvm_mmio_req ioreq; | ||
316 | struct kvm_pal_call pal_data; | ||
317 | struct kvm_sal_call sal_data; | ||
318 | struct kvm_switch_rr6 rr_data; | ||
319 | struct kvm_ipi_data ipi_data; | ||
320 | struct kvm_ptc_g ptc_g_data; | ||
321 | } u; | ||
322 | }; | ||
323 | |||
324 | union pte_flags { | ||
325 | unsigned long val; | ||
326 | struct { | ||
327 | unsigned long p : 1; /*0 */ | ||
328 | unsigned long : 1; /* 1 */ | ||
329 | unsigned long ma : 3; /* 2-4 */ | ||
330 | unsigned long a : 1; /* 5 */ | ||
331 | unsigned long d : 1; /* 6 */ | ||
332 | unsigned long pl : 2; /* 7-8 */ | ||
333 | unsigned long ar : 3; /* 9-11 */ | ||
334 | unsigned long ppn : 38; /* 12-49 */ | ||
335 | unsigned long : 2; /* 50-51 */ | ||
336 | unsigned long ed : 1; /* 52 */ | ||
337 | }; | ||
338 | }; | ||
339 | |||
340 | union ia64_pta { | ||
341 | unsigned long val; | ||
342 | struct { | ||
343 | unsigned long ve : 1; | ||
344 | unsigned long reserved0 : 1; | ||
345 | unsigned long size : 6; | ||
346 | unsigned long vf : 1; | ||
347 | unsigned long reserved1 : 6; | ||
348 | unsigned long base : 49; | ||
349 | }; | ||
350 | }; | ||
351 | |||
352 | struct thash_cb { | ||
353 | /* THASH base information */ | ||
354 | struct thash_data *hash; /* hash table pointer */ | ||
355 | union ia64_pta pta; | ||
356 | int num; | ||
357 | }; | ||
358 | |||
359 | struct kvm_vcpu_stat { | ||
360 | u32 halt_wakeup; | ||
361 | }; | ||
362 | |||
363 | struct kvm_vcpu_arch { | ||
364 | int launched; | ||
365 | int last_exit; | ||
366 | int last_run_cpu; | ||
367 | int vmm_tr_slot; | ||
368 | int vm_tr_slot; | ||
369 | int sn_rtc_tr_slot; | ||
370 | |||
371 | #define KVM_MP_STATE_RUNNABLE 0 | ||
372 | #define KVM_MP_STATE_UNINITIALIZED 1 | ||
373 | #define KVM_MP_STATE_INIT_RECEIVED 2 | ||
374 | #define KVM_MP_STATE_HALTED 3 | ||
375 | int mp_state; | ||
376 | |||
377 | #define MAX_PTC_G_NUM 3 | ||
378 | int ptc_g_count; | ||
379 | struct kvm_ptc_g ptc_g_data[MAX_PTC_G_NUM]; | ||
380 | |||
381 | /*halt timer to wake up sleepy vcpus*/ | ||
382 | struct hrtimer hlt_timer; | ||
383 | long ht_active; | ||
384 | |||
385 | struct kvm_lapic *apic; /* kernel irqchip context */ | ||
386 | struct vpd *vpd; | ||
387 | |||
388 | /* Exit data for vmm_transition*/ | ||
389 | struct exit_ctl_data exit_data; | ||
390 | |||
391 | cpumask_t cache_coherent_map; | ||
392 | |||
393 | unsigned long vmm_rr; | ||
394 | unsigned long host_rr6; | ||
395 | unsigned long psbits[8]; | ||
396 | unsigned long cr_iipa; | ||
397 | unsigned long cr_isr; | ||
398 | unsigned long vsa_base; | ||
399 | unsigned long dirty_log_lock_pa; | ||
400 | unsigned long __gp; | ||
401 | /* TR and TC. */ | ||
402 | struct thash_data itrs[NITRS]; | ||
403 | struct thash_data dtrs[NDTRS]; | ||
404 | /* Bit is set if there is a tr/tc for the region. */ | ||
405 | unsigned char itr_regions; | ||
406 | unsigned char dtr_regions; | ||
407 | unsigned char tc_regions; | ||
408 | /* purge all */ | ||
409 | unsigned long ptce_base; | ||
410 | unsigned long ptce_count[2]; | ||
411 | unsigned long ptce_stride[2]; | ||
412 | /* itc/itm */ | ||
413 | unsigned long last_itc; | ||
414 | long itc_offset; | ||
415 | unsigned long itc_check; | ||
416 | unsigned long timer_check; | ||
417 | unsigned int timer_pending; | ||
418 | unsigned int timer_fired; | ||
419 | |||
420 | unsigned long vrr[8]; | ||
421 | unsigned long ibr[8]; | ||
422 | unsigned long dbr[8]; | ||
423 | unsigned long insvc[4]; /* Interrupt in service. */ | ||
424 | unsigned long xtp; | ||
425 | |||
426 | unsigned long metaphysical_rr0; /* from kvm_arch (so is pinned) */ | ||
427 | unsigned long metaphysical_rr4; /* from kvm_arch (so is pinned) */ | ||
428 | unsigned long metaphysical_saved_rr0; /* from kvm_arch */ | ||
429 | unsigned long metaphysical_saved_rr4; /* from kvm_arch */ | ||
430 | unsigned long fp_psr; /*used for lazy float register */ | ||
431 | unsigned long saved_gp; | ||
432 | /*for phycial emulation */ | ||
433 | int mode_flags; | ||
434 | struct thash_cb vtlb; | ||
435 | struct thash_cb vhpt; | ||
436 | char irq_check; | ||
437 | char irq_new_pending; | ||
438 | |||
439 | unsigned long opcode; | ||
440 | unsigned long cause; | ||
441 | char log_buf[VMM_LOG_LEN]; | ||
442 | union context host; | ||
443 | union context guest; | ||
444 | |||
445 | char mmio_data[8]; | ||
446 | }; | ||
447 | |||
448 | struct kvm_vm_stat { | ||
449 | u64 remote_tlb_flush; | ||
450 | }; | ||
451 | |||
452 | struct kvm_sal_data { | ||
453 | unsigned long boot_ip; | ||
454 | unsigned long boot_gp; | ||
455 | }; | ||
456 | |||
457 | struct kvm_arch_memory_slot { | ||
458 | }; | ||
459 | |||
460 | struct kvm_arch { | ||
461 | spinlock_t dirty_log_lock; | ||
462 | |||
463 | unsigned long vm_base; | ||
464 | unsigned long metaphysical_rr0; | ||
465 | unsigned long metaphysical_rr4; | ||
466 | unsigned long vmm_init_rr; | ||
467 | |||
468 | int is_sn2; | ||
469 | |||
470 | struct kvm_ioapic *vioapic; | ||
471 | struct kvm_vm_stat stat; | ||
472 | struct kvm_sal_data rdv_sal_data; | ||
473 | |||
474 | struct list_head assigned_dev_head; | ||
475 | struct iommu_domain *iommu_domain; | ||
476 | bool iommu_noncoherent; | ||
477 | |||
478 | unsigned long irq_sources_bitmap; | ||
479 | unsigned long irq_states[KVM_IOAPIC_NUM_PINS]; | ||
480 | }; | ||
481 | |||
482 | union cpuid3_t { | ||
483 | u64 value; | ||
484 | struct { | ||
485 | u64 number : 8; | ||
486 | u64 revision : 8; | ||
487 | u64 model : 8; | ||
488 | u64 family : 8; | ||
489 | u64 archrev : 8; | ||
490 | u64 rv : 24; | ||
491 | }; | ||
492 | }; | ||
493 | |||
494 | struct kvm_pt_regs { | ||
495 | /* The following registers are saved by SAVE_MIN: */ | ||
496 | unsigned long b6; /* scratch */ | ||
497 | unsigned long b7; /* scratch */ | ||
498 | |||
499 | unsigned long ar_csd; /* used by cmp8xchg16 (scratch) */ | ||
500 | unsigned long ar_ssd; /* reserved for future use (scratch) */ | ||
501 | |||
502 | unsigned long r8; /* scratch (return value register 0) */ | ||
503 | unsigned long r9; /* scratch (return value register 1) */ | ||
504 | unsigned long r10; /* scratch (return value register 2) */ | ||
505 | unsigned long r11; /* scratch (return value register 3) */ | ||
506 | |||
507 | unsigned long cr_ipsr; /* interrupted task's psr */ | ||
508 | unsigned long cr_iip; /* interrupted task's instruction pointer */ | ||
509 | unsigned long cr_ifs; /* interrupted task's function state */ | ||
510 | |||
511 | unsigned long ar_unat; /* interrupted task's NaT register (preserved) */ | ||
512 | unsigned long ar_pfs; /* prev function state */ | ||
513 | unsigned long ar_rsc; /* RSE configuration */ | ||
514 | /* The following two are valid only if cr_ipsr.cpl > 0: */ | ||
515 | unsigned long ar_rnat; /* RSE NaT */ | ||
516 | unsigned long ar_bspstore; /* RSE bspstore */ | ||
517 | |||
518 | unsigned long pr; /* 64 predicate registers (1 bit each) */ | ||
519 | unsigned long b0; /* return pointer (bp) */ | ||
520 | unsigned long loadrs; /* size of dirty partition << 16 */ | ||
521 | |||
522 | unsigned long r1; /* the gp pointer */ | ||
523 | unsigned long r12; /* interrupted task's memory stack pointer */ | ||
524 | unsigned long r13; /* thread pointer */ | ||
525 | |||
526 | unsigned long ar_fpsr; /* floating point status (preserved) */ | ||
527 | unsigned long r15; /* scratch */ | ||
528 | |||
529 | /* The remaining registers are NOT saved for system calls. */ | ||
530 | unsigned long r14; /* scratch */ | ||
531 | unsigned long r2; /* scratch */ | ||
532 | unsigned long r3; /* scratch */ | ||
533 | unsigned long r16; /* scratch */ | ||
534 | unsigned long r17; /* scratch */ | ||
535 | unsigned long r18; /* scratch */ | ||
536 | unsigned long r19; /* scratch */ | ||
537 | unsigned long r20; /* scratch */ | ||
538 | unsigned long r21; /* scratch */ | ||
539 | unsigned long r22; /* scratch */ | ||
540 | unsigned long r23; /* scratch */ | ||
541 | unsigned long r24; /* scratch */ | ||
542 | unsigned long r25; /* scratch */ | ||
543 | unsigned long r26; /* scratch */ | ||
544 | unsigned long r27; /* scratch */ | ||
545 | unsigned long r28; /* scratch */ | ||
546 | unsigned long r29; /* scratch */ | ||
547 | unsigned long r30; /* scratch */ | ||
548 | unsigned long r31; /* scratch */ | ||
549 | unsigned long ar_ccv; /* compare/exchange value (scratch) */ | ||
550 | |||
551 | /* | ||
552 | * Floating point registers that the kernel considers scratch: | ||
553 | */ | ||
554 | struct ia64_fpreg f6; /* scratch */ | ||
555 | struct ia64_fpreg f7; /* scratch */ | ||
556 | struct ia64_fpreg f8; /* scratch */ | ||
557 | struct ia64_fpreg f9; /* scratch */ | ||
558 | struct ia64_fpreg f10; /* scratch */ | ||
559 | struct ia64_fpreg f11; /* scratch */ | ||
560 | |||
561 | unsigned long r4; /* preserved */ | ||
562 | unsigned long r5; /* preserved */ | ||
563 | unsigned long r6; /* preserved */ | ||
564 | unsigned long r7; /* preserved */ | ||
565 | unsigned long eml_unat; /* used for emulating instruction */ | ||
566 | unsigned long pad0; /* alignment pad */ | ||
567 | }; | ||
568 | |||
569 | static inline struct kvm_pt_regs *vcpu_regs(struct kvm_vcpu *v) | ||
570 | { | ||
571 | return (struct kvm_pt_regs *) ((unsigned long) v + KVM_STK_OFFSET) - 1; | ||
572 | } | ||
573 | |||
574 | typedef int kvm_vmm_entry(void); | ||
575 | typedef void kvm_tramp_entry(union context *host, union context *guest); | ||
576 | |||
577 | struct kvm_vmm_info{ | ||
578 | struct module *module; | ||
579 | kvm_vmm_entry *vmm_entry; | ||
580 | kvm_tramp_entry *tramp_entry; | ||
581 | unsigned long vmm_ivt; | ||
582 | unsigned long patch_mov_ar; | ||
583 | unsigned long patch_mov_ar_sn2; | ||
584 | }; | ||
585 | |||
586 | int kvm_highest_pending_irq(struct kvm_vcpu *vcpu); | ||
587 | int kvm_emulate_halt(struct kvm_vcpu *vcpu); | ||
588 | int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run); | ||
589 | void kvm_sal_emul(struct kvm_vcpu *vcpu); | ||
590 | |||
591 | #define __KVM_HAVE_ARCH_VM_ALLOC 1 | ||
592 | struct kvm *kvm_arch_alloc_vm(void); | ||
593 | void kvm_arch_free_vm(struct kvm *kvm); | ||
594 | |||
595 | static inline void kvm_arch_sync_events(struct kvm *kvm) {} | ||
596 | static inline void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) {} | ||
597 | static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu) {} | ||
598 | static inline void kvm_arch_free_memslot(struct kvm *kvm, | ||
599 | struct kvm_memory_slot *free, struct kvm_memory_slot *dont) {} | ||
600 | static inline void kvm_arch_memslots_updated(struct kvm *kvm) {} | ||
601 | static inline void kvm_arch_commit_memory_region(struct kvm *kvm, | ||
602 | struct kvm_userspace_memory_region *mem, | ||
603 | const struct kvm_memory_slot *old, | ||
604 | enum kvm_mr_change change) {} | ||
605 | static inline void kvm_arch_hardware_unsetup(void) {} | ||
606 | |||
607 | #endif /* __ASSEMBLY__*/ | ||
608 | |||
609 | #endif | ||
diff --git a/arch/ia64/include/asm/pvclock-abi.h b/arch/ia64/include/asm/pvclock-abi.h deleted file mode 100644 index 42b233bedeb5..000000000000 --- a/arch/ia64/include/asm/pvclock-abi.h +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /* | ||
2 | * same structure to x86's | ||
3 | * Hopefully asm-x86/pvclock-abi.h would be moved to somewhere more generic. | ||
4 | * For now, define same duplicated definitions. | ||
5 | */ | ||
6 | |||
7 | #ifndef _ASM_IA64__PVCLOCK_ABI_H | ||
8 | #define _ASM_IA64__PVCLOCK_ABI_H | ||
9 | #ifndef __ASSEMBLY__ | ||
10 | |||
11 | /* | ||
12 | * These structs MUST NOT be changed. | ||
13 | * They are the ABI between hypervisor and guest OS. | ||
14 | * KVM is using this. | ||
15 | * | ||
16 | * pvclock_vcpu_time_info holds the system time and the tsc timestamp | ||
17 | * of the last update. So the guest can use the tsc delta to get a | ||
18 | * more precise system time. There is one per virtual cpu. | ||
19 | * | ||
20 | * pvclock_wall_clock references the point in time when the system | ||
21 | * time was zero (usually boot time), thus the guest calculates the | ||
22 | * current wall clock by adding the system time. | ||
23 | * | ||
24 | * Protocol for the "version" fields is: hypervisor raises it (making | ||
25 | * it uneven) before it starts updating the fields and raises it again | ||
26 | * (making it even) when it is done. Thus the guest can make sure the | ||
27 | * time values it got are consistent by checking the version before | ||
28 | * and after reading them. | ||
29 | */ | ||
30 | |||
31 | struct pvclock_vcpu_time_info { | ||
32 | u32 version; | ||
33 | u32 pad0; | ||
34 | u64 tsc_timestamp; | ||
35 | u64 system_time; | ||
36 | u32 tsc_to_system_mul; | ||
37 | s8 tsc_shift; | ||
38 | u8 pad[3]; | ||
39 | } __attribute__((__packed__)); /* 32 bytes */ | ||
40 | |||
41 | struct pvclock_wall_clock { | ||
42 | u32 version; | ||
43 | u32 sec; | ||
44 | u32 nsec; | ||
45 | } __attribute__((__packed__)); | ||
46 | |||
47 | #endif /* __ASSEMBLY__ */ | ||
48 | #endif /* _ASM_IA64__PVCLOCK_ABI_H */ | ||
diff --git a/arch/ia64/include/uapi/asm/kvm.h b/arch/ia64/include/uapi/asm/kvm.h deleted file mode 100644 index 99503c284400..000000000000 --- a/arch/ia64/include/uapi/asm/kvm.h +++ /dev/null | |||
@@ -1,268 +0,0 @@ | |||
1 | #ifndef __ASM_IA64_KVM_H | ||
2 | #define __ASM_IA64_KVM_H | ||
3 | |||
4 | /* | ||
5 | * kvm structure definitions for ia64 | ||
6 | * | ||
7 | * Copyright (C) 2007 Xiantao Zhang <xiantao.zhang@intel.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms and conditions of the GNU General Public License, | ||
11 | * version 2, as published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along with | ||
19 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | ||
20 | * Place - Suite 330, Boston, MA 02111-1307 USA. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include <linux/types.h> | ||
25 | #include <linux/ioctl.h> | ||
26 | |||
27 | /* Select x86 specific features in <linux/kvm.h> */ | ||
28 | #define __KVM_HAVE_IOAPIC | ||
29 | #define __KVM_HAVE_IRQ_LINE | ||
30 | |||
31 | /* Architectural interrupt line count. */ | ||
32 | #define KVM_NR_INTERRUPTS 256 | ||
33 | |||
34 | #define KVM_IOAPIC_NUM_PINS 48 | ||
35 | |||
36 | struct kvm_ioapic_state { | ||
37 | __u64 base_address; | ||
38 | __u32 ioregsel; | ||
39 | __u32 id; | ||
40 | __u32 irr; | ||
41 | __u32 pad; | ||
42 | union { | ||
43 | __u64 bits; | ||
44 | struct { | ||
45 | __u8 vector; | ||
46 | __u8 delivery_mode:3; | ||
47 | __u8 dest_mode:1; | ||
48 | __u8 delivery_status:1; | ||
49 | __u8 polarity:1; | ||
50 | __u8 remote_irr:1; | ||
51 | __u8 trig_mode:1; | ||
52 | __u8 mask:1; | ||
53 | __u8 reserve:7; | ||
54 | __u8 reserved[4]; | ||
55 | __u8 dest_id; | ||
56 | } fields; | ||
57 | } redirtbl[KVM_IOAPIC_NUM_PINS]; | ||
58 | }; | ||
59 | |||
60 | #define KVM_IRQCHIP_PIC_MASTER 0 | ||
61 | #define KVM_IRQCHIP_PIC_SLAVE 1 | ||
62 | #define KVM_IRQCHIP_IOAPIC 2 | ||
63 | #define KVM_NR_IRQCHIPS 3 | ||
64 | |||
65 | #define KVM_CONTEXT_SIZE 8*1024 | ||
66 | |||
67 | struct kvm_fpreg { | ||
68 | union { | ||
69 | unsigned long bits[2]; | ||
70 | long double __dummy; /* force 16-byte alignment */ | ||
71 | } u; | ||
72 | }; | ||
73 | |||
74 | union context { | ||
75 | /* 8K size */ | ||
76 | char dummy[KVM_CONTEXT_SIZE]; | ||
77 | struct { | ||
78 | unsigned long psr; | ||
79 | unsigned long pr; | ||
80 | unsigned long caller_unat; | ||
81 | unsigned long pad; | ||
82 | unsigned long gr[32]; | ||
83 | unsigned long ar[128]; | ||
84 | unsigned long br[8]; | ||
85 | unsigned long cr[128]; | ||
86 | unsigned long rr[8]; | ||
87 | unsigned long ibr[8]; | ||
88 | unsigned long dbr[8]; | ||
89 | unsigned long pkr[8]; | ||
90 | struct kvm_fpreg fr[128]; | ||
91 | }; | ||
92 | }; | ||
93 | |||
94 | struct thash_data { | ||
95 | union { | ||
96 | struct { | ||
97 | unsigned long p : 1; /* 0 */ | ||
98 | unsigned long rv1 : 1; /* 1 */ | ||
99 | unsigned long ma : 3; /* 2-4 */ | ||
100 | unsigned long a : 1; /* 5 */ | ||
101 | unsigned long d : 1; /* 6 */ | ||
102 | unsigned long pl : 2; /* 7-8 */ | ||
103 | unsigned long ar : 3; /* 9-11 */ | ||
104 | unsigned long ppn : 38; /* 12-49 */ | ||
105 | unsigned long rv2 : 2; /* 50-51 */ | ||
106 | unsigned long ed : 1; /* 52 */ | ||
107 | unsigned long ig1 : 11; /* 53-63 */ | ||
108 | }; | ||
109 | struct { | ||
110 | unsigned long __rv1 : 53; /* 0-52 */ | ||
111 | unsigned long contiguous : 1; /*53 */ | ||
112 | unsigned long tc : 1; /* 54 TR or TC */ | ||
113 | unsigned long cl : 1; | ||
114 | /* 55 I side or D side cache line */ | ||
115 | unsigned long len : 4; /* 56-59 */ | ||
116 | unsigned long io : 1; /* 60 entry is for io or not */ | ||
117 | unsigned long nomap : 1; | ||
118 | /* 61 entry cann't be inserted into machine TLB.*/ | ||
119 | unsigned long checked : 1; | ||
120 | /* 62 for VTLB/VHPT sanity check */ | ||
121 | unsigned long invalid : 1; | ||
122 | /* 63 invalid entry */ | ||
123 | }; | ||
124 | unsigned long page_flags; | ||
125 | }; /* same for VHPT and TLB */ | ||
126 | |||
127 | union { | ||
128 | struct { | ||
129 | unsigned long rv3 : 2; | ||
130 | unsigned long ps : 6; | ||
131 | unsigned long key : 24; | ||
132 | unsigned long rv4 : 32; | ||
133 | }; | ||
134 | unsigned long itir; | ||
135 | }; | ||
136 | union { | ||
137 | struct { | ||
138 | unsigned long ig2 : 12; | ||
139 | unsigned long vpn : 49; | ||
140 | unsigned long vrn : 3; | ||
141 | }; | ||
142 | unsigned long ifa; | ||
143 | unsigned long vadr; | ||
144 | struct { | ||
145 | unsigned long tag : 63; | ||
146 | unsigned long ti : 1; | ||
147 | }; | ||
148 | unsigned long etag; | ||
149 | }; | ||
150 | union { | ||
151 | struct thash_data *next; | ||
152 | unsigned long rid; | ||
153 | unsigned long gpaddr; | ||
154 | }; | ||
155 | }; | ||
156 | |||
157 | #define NITRS 8 | ||
158 | #define NDTRS 8 | ||
159 | |||
160 | struct saved_vpd { | ||
161 | unsigned long vhpi; | ||
162 | unsigned long vgr[16]; | ||
163 | unsigned long vbgr[16]; | ||
164 | unsigned long vnat; | ||
165 | unsigned long vbnat; | ||
166 | unsigned long vcpuid[5]; | ||
167 | unsigned long vpsr; | ||
168 | unsigned long vpr; | ||
169 | union { | ||
170 | unsigned long vcr[128]; | ||
171 | struct { | ||
172 | unsigned long dcr; | ||
173 | unsigned long itm; | ||
174 | unsigned long iva; | ||
175 | unsigned long rsv1[5]; | ||
176 | unsigned long pta; | ||
177 | unsigned long rsv2[7]; | ||
178 | unsigned long ipsr; | ||
179 | unsigned long isr; | ||
180 | unsigned long rsv3; | ||
181 | unsigned long iip; | ||
182 | unsigned long ifa; | ||
183 | unsigned long itir; | ||
184 | unsigned long iipa; | ||
185 | unsigned long ifs; | ||
186 | unsigned long iim; | ||
187 | unsigned long iha; | ||
188 | unsigned long rsv4[38]; | ||
189 | unsigned long lid; | ||
190 | unsigned long ivr; | ||
191 | unsigned long tpr; | ||
192 | unsigned long eoi; | ||
193 | unsigned long irr[4]; | ||
194 | unsigned long itv; | ||
195 | unsigned long pmv; | ||
196 | unsigned long cmcv; | ||
197 | unsigned long rsv5[5]; | ||
198 | unsigned long lrr0; | ||
199 | unsigned long lrr1; | ||
200 | unsigned long rsv6[46]; | ||
201 | }; | ||
202 | }; | ||
203 | }; | ||
204 | |||
205 | struct kvm_regs { | ||
206 | struct saved_vpd vpd; | ||
207 | /*Arch-regs*/ | ||
208 | int mp_state; | ||
209 | unsigned long vmm_rr; | ||
210 | /* TR and TC. */ | ||
211 | struct thash_data itrs[NITRS]; | ||
212 | struct thash_data dtrs[NDTRS]; | ||
213 | /* Bit is set if there is a tr/tc for the region. */ | ||
214 | unsigned char itr_regions; | ||
215 | unsigned char dtr_regions; | ||
216 | unsigned char tc_regions; | ||
217 | |||
218 | char irq_check; | ||
219 | unsigned long saved_itc; | ||
220 | unsigned long itc_check; | ||
221 | unsigned long timer_check; | ||
222 | unsigned long timer_pending; | ||
223 | unsigned long last_itc; | ||
224 | |||
225 | unsigned long vrr[8]; | ||
226 | unsigned long ibr[8]; | ||
227 | unsigned long dbr[8]; | ||
228 | unsigned long insvc[4]; /* Interrupt in service. */ | ||
229 | unsigned long xtp; | ||
230 | |||
231 | unsigned long metaphysical_rr0; /* from kvm_arch (so is pinned) */ | ||
232 | unsigned long metaphysical_rr4; /* from kvm_arch (so is pinned) */ | ||
233 | unsigned long metaphysical_saved_rr0; /* from kvm_arch */ | ||
234 | unsigned long metaphysical_saved_rr4; /* from kvm_arch */ | ||
235 | unsigned long fp_psr; /*used for lazy float register */ | ||
236 | unsigned long saved_gp; | ||
237 | /*for phycial emulation */ | ||
238 | |||
239 | union context saved_guest; | ||
240 | |||
241 | unsigned long reserved[64]; /* for future use */ | ||
242 | }; | ||
243 | |||
244 | struct kvm_sregs { | ||
245 | }; | ||
246 | |||
247 | struct kvm_fpu { | ||
248 | }; | ||
249 | |||
250 | #define KVM_IA64_VCPU_STACK_SHIFT 16 | ||
251 | #define KVM_IA64_VCPU_STACK_SIZE (1UL << KVM_IA64_VCPU_STACK_SHIFT) | ||
252 | |||
253 | struct kvm_ia64_vcpu_stack { | ||
254 | unsigned char stack[KVM_IA64_VCPU_STACK_SIZE]; | ||
255 | }; | ||
256 | |||
257 | struct kvm_debug_exit_arch { | ||
258 | }; | ||
259 | |||
260 | /* for KVM_SET_GUEST_DEBUG */ | ||
261 | struct kvm_guest_debug_arch { | ||
262 | }; | ||
263 | |||
264 | /* definition of registers in kvm_run */ | ||
265 | struct kvm_sync_regs { | ||
266 | }; | ||
267 | |||
268 | #endif | ||
diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig deleted file mode 100644 index 3d50ea955c4c..000000000000 --- a/arch/ia64/kvm/Kconfig +++ /dev/null | |||
@@ -1,66 +0,0 @@ | |||
1 | # | ||
2 | # KVM configuration | ||
3 | # | ||
4 | |||
5 | source "virt/kvm/Kconfig" | ||
6 | |||
7 | menuconfig VIRTUALIZATION | ||
8 | bool "Virtualization" | ||
9 | depends on HAVE_KVM || IA64 | ||
10 | default y | ||
11 | ---help--- | ||
12 | Say Y here to get to see options for using your Linux host to run other | ||
13 | operating systems inside virtual machines (guests). | ||
14 | This option alone does not add any kernel code. | ||
15 | |||
16 | If you say N, all options in this submenu will be skipped and disabled. | ||
17 | |||
18 | if VIRTUALIZATION | ||
19 | |||
20 | config KVM | ||
21 | tristate "Kernel-based Virtual Machine (KVM) support" | ||
22 | depends on BROKEN | ||
23 | depends on HAVE_KVM && MODULES | ||
24 | depends on BROKEN | ||
25 | select PREEMPT_NOTIFIERS | ||
26 | select ANON_INODES | ||
27 | select HAVE_KVM_IRQCHIP | ||
28 | select HAVE_KVM_IRQFD | ||
29 | select HAVE_KVM_IRQ_ROUTING | ||
30 | select KVM_APIC_ARCHITECTURE | ||
31 | select KVM_MMIO | ||
32 | ---help--- | ||
33 | Support hosting fully virtualized guest machines using hardware | ||
34 | virtualization extensions. You will need a fairly recent | ||
35 | processor equipped with virtualization extensions. You will also | ||
36 | need to select one or more of the processor modules below. | ||
37 | |||
38 | This module provides access to the hardware capabilities through | ||
39 | a character device node named /dev/kvm. | ||
40 | |||
41 | To compile this as a module, choose M here: the module | ||
42 | will be called kvm. | ||
43 | |||
44 | If unsure, say N. | ||
45 | |||
46 | config KVM_INTEL | ||
47 | tristate "KVM for Intel Itanium 2 processors support" | ||
48 | depends on KVM && m | ||
49 | ---help--- | ||
50 | Provides support for KVM on Itanium 2 processors equipped with the VT | ||
51 | extensions. | ||
52 | |||
53 | config KVM_DEVICE_ASSIGNMENT | ||
54 | bool "KVM legacy PCI device assignment support" | ||
55 | depends on KVM && PCI && IOMMU_API | ||
56 | default y | ||
57 | ---help--- | ||
58 | Provide support for legacy PCI device assignment through KVM. The | ||
59 | kernel now also supports a full featured userspace device driver | ||
60 | framework through VFIO, which supersedes much of this support. | ||
61 | |||
62 | If unsure, say Y. | ||
63 | |||
64 | source drivers/vhost/Kconfig | ||
65 | |||
66 | endif # VIRTUALIZATION | ||
diff --git a/arch/ia64/kvm/Makefile b/arch/ia64/kvm/Makefile deleted file mode 100644 index 18e45ec49bbf..000000000000 --- a/arch/ia64/kvm/Makefile +++ /dev/null | |||
@@ -1,67 +0,0 @@ | |||
1 | #This Make file is to generate asm-offsets.h and build source. | ||
2 | # | ||
3 | |||
4 | #Generate asm-offsets.h for vmm module build | ||
5 | offsets-file := asm-offsets.h | ||
6 | |||
7 | always := $(offsets-file) | ||
8 | targets := $(offsets-file) | ||
9 | targets += arch/ia64/kvm/asm-offsets.s | ||
10 | |||
11 | # Default sed regexp - multiline due to syntax constraints | ||
12 | define sed-y | ||
13 | "/^->/{s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; s:->::; p;}" | ||
14 | endef | ||
15 | |||
16 | quiet_cmd_offsets = GEN $@ | ||
17 | define cmd_offsets | ||
18 | (set -e; \ | ||
19 | echo "#ifndef __ASM_KVM_OFFSETS_H__"; \ | ||
20 | echo "#define __ASM_KVM_OFFSETS_H__"; \ | ||
21 | echo "/*"; \ | ||
22 | echo " * DO NOT MODIFY."; \ | ||
23 | echo " *"; \ | ||
24 | echo " * This file was generated by Makefile"; \ | ||
25 | echo " *"; \ | ||
26 | echo " */"; \ | ||
27 | echo ""; \ | ||
28 | sed -ne $(sed-y) $<; \ | ||
29 | echo ""; \ | ||
30 | echo "#endif" ) > $@ | ||
31 | endef | ||
32 | |||
33 | # We use internal rules to avoid the "is up to date" message from make | ||
34 | arch/ia64/kvm/asm-offsets.s: arch/ia64/kvm/asm-offsets.c \ | ||
35 | $(wildcard $(srctree)/arch/ia64/include/asm/*.h)\ | ||
36 | $(wildcard $(srctree)/include/linux/*.h) | ||
37 | $(call if_changed_dep,cc_s_c) | ||
38 | |||
39 | $(obj)/$(offsets-file): arch/ia64/kvm/asm-offsets.s | ||
40 | $(call cmd,offsets) | ||
41 | |||
42 | FORCE : $(obj)/$(offsets-file) | ||
43 | |||
44 | # | ||
45 | # Makefile for Kernel-based Virtual Machine module | ||
46 | # | ||
47 | |||
48 | ccflags-y := -Ivirt/kvm -Iarch/ia64/kvm/ | ||
49 | asflags-y := -Ivirt/kvm -Iarch/ia64/kvm/ | ||
50 | KVM := ../../../virt/kvm | ||
51 | |||
52 | common-objs = $(KVM)/kvm_main.o $(KVM)/ioapic.o \ | ||
53 | $(KVM)/coalesced_mmio.o $(KVM)/irq_comm.o | ||
54 | |||
55 | ifeq ($(CONFIG_KVM_DEVICE_ASSIGNMENT),y) | ||
56 | common-objs += $(KVM)/assigned-dev.o $(KVM)/iommu.o | ||
57 | endif | ||
58 | |||
59 | kvm-objs := $(common-objs) kvm-ia64.o kvm_fw.o | ||
60 | obj-$(CONFIG_KVM) += kvm.o | ||
61 | |||
62 | CFLAGS_vcpu.o += -mfixed-range=f2-f5,f12-f127 | ||
63 | kvm-intel-objs = vmm.o vmm_ivt.o trampoline.o vcpu.o optvfault.o mmio.o \ | ||
64 | vtlb.o process.o kvm_lib.o | ||
65 | #Add link memcpy and memset to avoid possible structure assignment error | ||
66 | kvm-intel-objs += memcpy.o memset.o | ||
67 | obj-$(CONFIG_KVM_INTEL) += kvm-intel.o | ||
diff --git a/arch/ia64/kvm/asm-offsets.c b/arch/ia64/kvm/asm-offsets.c deleted file mode 100644 index 9324c875caf5..000000000000 --- a/arch/ia64/kvm/asm-offsets.c +++ /dev/null | |||
@@ -1,241 +0,0 @@ | |||
1 | /* | ||
2 | * asm-offsets.c Generate definitions needed by assembly language modules. | ||
3 | * This code generates raw asm output which is post-processed | ||
4 | * to extract and format the required data. | ||
5 | * | ||
6 | * Anthony Xu <anthony.xu@intel.com> | ||
7 | * Xiantao Zhang <xiantao.zhang@intel.com> | ||
8 | * Copyright (c) 2007 Intel Corporation KVM support. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms and conditions of the GNU General Public License, | ||
12 | * version 2, as published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
15 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
17 | * more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along with | ||
20 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | ||
21 | * Place - Suite 330, Boston, MA 02111-1307 USA. | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #include <linux/kvm_host.h> | ||
26 | #include <linux/kbuild.h> | ||
27 | |||
28 | #include "vcpu.h" | ||
29 | |||
30 | void foo(void) | ||
31 | { | ||
32 | DEFINE(VMM_TASK_SIZE, sizeof(struct kvm_vcpu)); | ||
33 | DEFINE(VMM_PT_REGS_SIZE, sizeof(struct kvm_pt_regs)); | ||
34 | |||
35 | BLANK(); | ||
36 | |||
37 | DEFINE(VMM_VCPU_META_RR0_OFFSET, | ||
38 | offsetof(struct kvm_vcpu, arch.metaphysical_rr0)); | ||
39 | DEFINE(VMM_VCPU_META_SAVED_RR0_OFFSET, | ||
40 | offsetof(struct kvm_vcpu, | ||
41 | arch.metaphysical_saved_rr0)); | ||
42 | DEFINE(VMM_VCPU_VRR0_OFFSET, | ||
43 | offsetof(struct kvm_vcpu, arch.vrr[0])); | ||
44 | DEFINE(VMM_VPD_IRR0_OFFSET, | ||
45 | offsetof(struct vpd, irr[0])); | ||
46 | DEFINE(VMM_VCPU_ITC_CHECK_OFFSET, | ||
47 | offsetof(struct kvm_vcpu, arch.itc_check)); | ||
48 | DEFINE(VMM_VCPU_IRQ_CHECK_OFFSET, | ||
49 | offsetof(struct kvm_vcpu, arch.irq_check)); | ||
50 | DEFINE(VMM_VPD_VHPI_OFFSET, | ||
51 | offsetof(struct vpd, vhpi)); | ||
52 | DEFINE(VMM_VCPU_VSA_BASE_OFFSET, | ||
53 | offsetof(struct kvm_vcpu, arch.vsa_base)); | ||
54 | DEFINE(VMM_VCPU_VPD_OFFSET, | ||
55 | offsetof(struct kvm_vcpu, arch.vpd)); | ||
56 | DEFINE(VMM_VCPU_IRQ_CHECK, | ||
57 | offsetof(struct kvm_vcpu, arch.irq_check)); | ||
58 | DEFINE(VMM_VCPU_TIMER_PENDING, | ||
59 | offsetof(struct kvm_vcpu, arch.timer_pending)); | ||
60 | DEFINE(VMM_VCPU_META_SAVED_RR0_OFFSET, | ||
61 | offsetof(struct kvm_vcpu, arch.metaphysical_saved_rr0)); | ||
62 | DEFINE(VMM_VCPU_MODE_FLAGS_OFFSET, | ||
63 | offsetof(struct kvm_vcpu, arch.mode_flags)); | ||
64 | DEFINE(VMM_VCPU_ITC_OFS_OFFSET, | ||
65 | offsetof(struct kvm_vcpu, arch.itc_offset)); | ||
66 | DEFINE(VMM_VCPU_LAST_ITC_OFFSET, | ||
67 | offsetof(struct kvm_vcpu, arch.last_itc)); | ||
68 | DEFINE(VMM_VCPU_SAVED_GP_OFFSET, | ||
69 | offsetof(struct kvm_vcpu, arch.saved_gp)); | ||
70 | |||
71 | BLANK(); | ||
72 | |||
73 | DEFINE(VMM_PT_REGS_B6_OFFSET, | ||
74 | offsetof(struct kvm_pt_regs, b6)); | ||
75 | DEFINE(VMM_PT_REGS_B7_OFFSET, | ||
76 | offsetof(struct kvm_pt_regs, b7)); | ||
77 | DEFINE(VMM_PT_REGS_AR_CSD_OFFSET, | ||
78 | offsetof(struct kvm_pt_regs, ar_csd)); | ||
79 | DEFINE(VMM_PT_REGS_AR_SSD_OFFSET, | ||
80 | offsetof(struct kvm_pt_regs, ar_ssd)); | ||
81 | DEFINE(VMM_PT_REGS_R8_OFFSET, | ||
82 | offsetof(struct kvm_pt_regs, r8)); | ||
83 | DEFINE(VMM_PT_REGS_R9_OFFSET, | ||
84 | offsetof(struct kvm_pt_regs, r9)); | ||
85 | DEFINE(VMM_PT_REGS_R10_OFFSET, | ||
86 | offsetof(struct kvm_pt_regs, r10)); | ||
87 | DEFINE(VMM_PT_REGS_R11_OFFSET, | ||
88 | offsetof(struct kvm_pt_regs, r11)); | ||
89 | DEFINE(VMM_PT_REGS_CR_IPSR_OFFSET, | ||
90 | offsetof(struct kvm_pt_regs, cr_ipsr)); | ||
91 | DEFINE(VMM_PT_REGS_CR_IIP_OFFSET, | ||
92 | offsetof(struct kvm_pt_regs, cr_iip)); | ||
93 | DEFINE(VMM_PT_REGS_CR_IFS_OFFSET, | ||
94 | offsetof(struct kvm_pt_regs, cr_ifs)); | ||
95 | DEFINE(VMM_PT_REGS_AR_UNAT_OFFSET, | ||
96 | offsetof(struct kvm_pt_regs, ar_unat)); | ||
97 | DEFINE(VMM_PT_REGS_AR_PFS_OFFSET, | ||
98 | offsetof(struct kvm_pt_regs, ar_pfs)); | ||
99 | DEFINE(VMM_PT_REGS_AR_RSC_OFFSET, | ||
100 | offsetof(struct kvm_pt_regs, ar_rsc)); | ||
101 | DEFINE(VMM_PT_REGS_AR_RNAT_OFFSET, | ||
102 | offsetof(struct kvm_pt_regs, ar_rnat)); | ||
103 | |||
104 | DEFINE(VMM_PT_REGS_AR_BSPSTORE_OFFSET, | ||
105 | offsetof(struct kvm_pt_regs, ar_bspstore)); | ||
106 | DEFINE(VMM_PT_REGS_PR_OFFSET, | ||
107 | offsetof(struct kvm_pt_regs, pr)); | ||
108 | DEFINE(VMM_PT_REGS_B0_OFFSET, | ||
109 | offsetof(struct kvm_pt_regs, b0)); | ||
110 | DEFINE(VMM_PT_REGS_LOADRS_OFFSET, | ||
111 | offsetof(struct kvm_pt_regs, loadrs)); | ||
112 | DEFINE(VMM_PT_REGS_R1_OFFSET, | ||
113 | offsetof(struct kvm_pt_regs, r1)); | ||
114 | DEFINE(VMM_PT_REGS_R12_OFFSET, | ||
115 | offsetof(struct kvm_pt_regs, r12)); | ||
116 | DEFINE(VMM_PT_REGS_R13_OFFSET, | ||
117 | offsetof(struct kvm_pt_regs, r13)); | ||
118 | DEFINE(VMM_PT_REGS_AR_FPSR_OFFSET, | ||
119 | offsetof(struct kvm_pt_regs, ar_fpsr)); | ||
120 | DEFINE(VMM_PT_REGS_R15_OFFSET, | ||
121 | offsetof(struct kvm_pt_regs, r15)); | ||
122 | DEFINE(VMM_PT_REGS_R14_OFFSET, | ||
123 | offsetof(struct kvm_pt_regs, r14)); | ||
124 | DEFINE(VMM_PT_REGS_R2_OFFSET, | ||
125 | offsetof(struct kvm_pt_regs, r2)); | ||
126 | DEFINE(VMM_PT_REGS_R3_OFFSET, | ||
127 | offsetof(struct kvm_pt_regs, r3)); | ||
128 | DEFINE(VMM_PT_REGS_R16_OFFSET, | ||
129 | offsetof(struct kvm_pt_regs, r16)); | ||
130 | DEFINE(VMM_PT_REGS_R17_OFFSET, | ||
131 | offsetof(struct kvm_pt_regs, r17)); | ||
132 | DEFINE(VMM_PT_REGS_R18_OFFSET, | ||
133 | offsetof(struct kvm_pt_regs, r18)); | ||
134 | DEFINE(VMM_PT_REGS_R19_OFFSET, | ||
135 | offsetof(struct kvm_pt_regs, r19)); | ||
136 | DEFINE(VMM_PT_REGS_R20_OFFSET, | ||
137 | offsetof(struct kvm_pt_regs, r20)); | ||
138 | DEFINE(VMM_PT_REGS_R21_OFFSET, | ||
139 | offsetof(struct kvm_pt_regs, r21)); | ||
140 | DEFINE(VMM_PT_REGS_R22_OFFSET, | ||
141 | offsetof(struct kvm_pt_regs, r22)); | ||
142 | DEFINE(VMM_PT_REGS_R23_OFFSET, | ||
143 | offsetof(struct kvm_pt_regs, r23)); | ||
144 | DEFINE(VMM_PT_REGS_R24_OFFSET, | ||
145 | offsetof(struct kvm_pt_regs, r24)); | ||
146 | DEFINE(VMM_PT_REGS_R25_OFFSET, | ||
147 | offsetof(struct kvm_pt_regs, r25)); | ||
148 | DEFINE(VMM_PT_REGS_R26_OFFSET, | ||
149 | offsetof(struct kvm_pt_regs, r26)); | ||
150 | DEFINE(VMM_PT_REGS_R27_OFFSET, | ||
151 | offsetof(struct kvm_pt_regs, r27)); | ||
152 | DEFINE(VMM_PT_REGS_R28_OFFSET, | ||
153 | offsetof(struct kvm_pt_regs, r28)); | ||
154 | DEFINE(VMM_PT_REGS_R29_OFFSET, | ||
155 | offsetof(struct kvm_pt_regs, r29)); | ||
156 | DEFINE(VMM_PT_REGS_R30_OFFSET, | ||
157 | offsetof(struct kvm_pt_regs, r30)); | ||
158 | DEFINE(VMM_PT_REGS_R31_OFFSET, | ||
159 | offsetof(struct kvm_pt_regs, r31)); | ||
160 | DEFINE(VMM_PT_REGS_AR_CCV_OFFSET, | ||
161 | offsetof(struct kvm_pt_regs, ar_ccv)); | ||
162 | DEFINE(VMM_PT_REGS_F6_OFFSET, | ||
163 | offsetof(struct kvm_pt_regs, f6)); | ||
164 | DEFINE(VMM_PT_REGS_F7_OFFSET, | ||
165 | offsetof(struct kvm_pt_regs, f7)); | ||
166 | DEFINE(VMM_PT_REGS_F8_OFFSET, | ||
167 | offsetof(struct kvm_pt_regs, f8)); | ||
168 | DEFINE(VMM_PT_REGS_F9_OFFSET, | ||
169 | offsetof(struct kvm_pt_regs, f9)); | ||
170 | DEFINE(VMM_PT_REGS_F10_OFFSET, | ||
171 | offsetof(struct kvm_pt_regs, f10)); | ||
172 | DEFINE(VMM_PT_REGS_F11_OFFSET, | ||
173 | offsetof(struct kvm_pt_regs, f11)); | ||
174 | DEFINE(VMM_PT_REGS_R4_OFFSET, | ||
175 | offsetof(struct kvm_pt_regs, r4)); | ||
176 | DEFINE(VMM_PT_REGS_R5_OFFSET, | ||
177 | offsetof(struct kvm_pt_regs, r5)); | ||
178 | DEFINE(VMM_PT_REGS_R6_OFFSET, | ||
179 | offsetof(struct kvm_pt_regs, r6)); | ||
180 | DEFINE(VMM_PT_REGS_R7_OFFSET, | ||
181 | offsetof(struct kvm_pt_regs, r7)); | ||
182 | DEFINE(VMM_PT_REGS_EML_UNAT_OFFSET, | ||
183 | offsetof(struct kvm_pt_regs, eml_unat)); | ||
184 | DEFINE(VMM_VCPU_IIPA_OFFSET, | ||
185 | offsetof(struct kvm_vcpu, arch.cr_iipa)); | ||
186 | DEFINE(VMM_VCPU_OPCODE_OFFSET, | ||
187 | offsetof(struct kvm_vcpu, arch.opcode)); | ||
188 | DEFINE(VMM_VCPU_CAUSE_OFFSET, offsetof(struct kvm_vcpu, arch.cause)); | ||
189 | DEFINE(VMM_VCPU_ISR_OFFSET, | ||
190 | offsetof(struct kvm_vcpu, arch.cr_isr)); | ||
191 | DEFINE(VMM_PT_REGS_R16_SLOT, | ||
192 | (((offsetof(struct kvm_pt_regs, r16) | ||
193 | - sizeof(struct kvm_pt_regs)) >> 3) & 0x3f)); | ||
194 | DEFINE(VMM_VCPU_MODE_FLAGS_OFFSET, | ||
195 | offsetof(struct kvm_vcpu, arch.mode_flags)); | ||
196 | DEFINE(VMM_VCPU_GP_OFFSET, offsetof(struct kvm_vcpu, arch.__gp)); | ||
197 | BLANK(); | ||
198 | |||
199 | DEFINE(VMM_VPD_BASE_OFFSET, offsetof(struct kvm_vcpu, arch.vpd)); | ||
200 | DEFINE(VMM_VPD_VIFS_OFFSET, offsetof(struct vpd, ifs)); | ||
201 | DEFINE(VMM_VLSAPIC_INSVC_BASE_OFFSET, | ||
202 | offsetof(struct kvm_vcpu, arch.insvc[0])); | ||
203 | DEFINE(VMM_VPD_VPTA_OFFSET, offsetof(struct vpd, pta)); | ||
204 | DEFINE(VMM_VPD_VPSR_OFFSET, offsetof(struct vpd, vpsr)); | ||
205 | |||
206 | DEFINE(VMM_CTX_R4_OFFSET, offsetof(union context, gr[4])); | ||
207 | DEFINE(VMM_CTX_R5_OFFSET, offsetof(union context, gr[5])); | ||
208 | DEFINE(VMM_CTX_R12_OFFSET, offsetof(union context, gr[12])); | ||
209 | DEFINE(VMM_CTX_R13_OFFSET, offsetof(union context, gr[13])); | ||
210 | DEFINE(VMM_CTX_KR0_OFFSET, offsetof(union context, ar[0])); | ||
211 | DEFINE(VMM_CTX_KR1_OFFSET, offsetof(union context, ar[1])); | ||
212 | DEFINE(VMM_CTX_B0_OFFSET, offsetof(union context, br[0])); | ||
213 | DEFINE(VMM_CTX_B1_OFFSET, offsetof(union context, br[1])); | ||
214 | DEFINE(VMM_CTX_B2_OFFSET, offsetof(union context, br[2])); | ||
215 | DEFINE(VMM_CTX_RR0_OFFSET, offsetof(union context, rr[0])); | ||
216 | DEFINE(VMM_CTX_RSC_OFFSET, offsetof(union context, ar[16])); | ||
217 | DEFINE(VMM_CTX_BSPSTORE_OFFSET, offsetof(union context, ar[18])); | ||
218 | DEFINE(VMM_CTX_RNAT_OFFSET, offsetof(union context, ar[19])); | ||
219 | DEFINE(VMM_CTX_FCR_OFFSET, offsetof(union context, ar[21])); | ||
220 | DEFINE(VMM_CTX_EFLAG_OFFSET, offsetof(union context, ar[24])); | ||
221 | DEFINE(VMM_CTX_CFLG_OFFSET, offsetof(union context, ar[27])); | ||
222 | DEFINE(VMM_CTX_FSR_OFFSET, offsetof(union context, ar[28])); | ||
223 | DEFINE(VMM_CTX_FIR_OFFSET, offsetof(union context, ar[29])); | ||
224 | DEFINE(VMM_CTX_FDR_OFFSET, offsetof(union context, ar[30])); | ||
225 | DEFINE(VMM_CTX_UNAT_OFFSET, offsetof(union context, ar[36])); | ||
226 | DEFINE(VMM_CTX_FPSR_OFFSET, offsetof(union context, ar[40])); | ||
227 | DEFINE(VMM_CTX_PFS_OFFSET, offsetof(union context, ar[64])); | ||
228 | DEFINE(VMM_CTX_LC_OFFSET, offsetof(union context, ar[65])); | ||
229 | DEFINE(VMM_CTX_DCR_OFFSET, offsetof(union context, cr[0])); | ||
230 | DEFINE(VMM_CTX_IVA_OFFSET, offsetof(union context, cr[2])); | ||
231 | DEFINE(VMM_CTX_PTA_OFFSET, offsetof(union context, cr[8])); | ||
232 | DEFINE(VMM_CTX_IBR0_OFFSET, offsetof(union context, ibr[0])); | ||
233 | DEFINE(VMM_CTX_DBR0_OFFSET, offsetof(union context, dbr[0])); | ||
234 | DEFINE(VMM_CTX_F2_OFFSET, offsetof(union context, fr[2])); | ||
235 | DEFINE(VMM_CTX_F3_OFFSET, offsetof(union context, fr[3])); | ||
236 | DEFINE(VMM_CTX_F32_OFFSET, offsetof(union context, fr[32])); | ||
237 | DEFINE(VMM_CTX_F33_OFFSET, offsetof(union context, fr[33])); | ||
238 | DEFINE(VMM_CTX_PKR0_OFFSET, offsetof(union context, pkr[0])); | ||
239 | DEFINE(VMM_CTX_PSR_OFFSET, offsetof(union context, psr)); | ||
240 | BLANK(); | ||
241 | } | ||
diff --git a/arch/ia64/kvm/irq.h b/arch/ia64/kvm/irq.h deleted file mode 100644 index c0785a728271..000000000000 --- a/arch/ia64/kvm/irq.h +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
1 | /* | ||
2 | * irq.h: In-kernel interrupt controller related definitions | ||
3 | * Copyright (c) 2008, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | ||
16 | * Place - Suite 330, Boston, MA 02111-1307 USA. | ||
17 | * | ||
18 | * Authors: | ||
19 | * Xiantao Zhang <xiantao.zhang@intel.com> | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #ifndef __IRQ_H | ||
24 | #define __IRQ_H | ||
25 | |||
26 | #include "lapic.h" | ||
27 | |||
28 | static inline int irqchip_in_kernel(struct kvm *kvm) | ||
29 | { | ||
30 | return 1; | ||
31 | } | ||
32 | |||
33 | #endif | ||
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c deleted file mode 100644 index dbe46f43884d..000000000000 --- a/arch/ia64/kvm/kvm-ia64.c +++ /dev/null | |||
@@ -1,1942 +0,0 @@ | |||
1 | /* | ||
2 | * kvm_ia64.c: Basic KVM support On Itanium series processors | ||
3 | * | ||
4 | * | ||
5 | * Copyright (C) 2007, Intel Corporation. | ||
6 | * Xiantao Zhang (xiantao.zhang@intel.com) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms and conditions of the GNU General Public License, | ||
10 | * version 2, as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along with | ||
18 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | ||
19 | * Place - Suite 330, Boston, MA 02111-1307 USA. | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/errno.h> | ||
25 | #include <linux/percpu.h> | ||
26 | #include <linux/fs.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/smp.h> | ||
29 | #include <linux/kvm_host.h> | ||
30 | #include <linux/kvm.h> | ||
31 | #include <linux/bitops.h> | ||
32 | #include <linux/hrtimer.h> | ||
33 | #include <linux/uaccess.h> | ||
34 | #include <linux/iommu.h> | ||
35 | #include <linux/intel-iommu.h> | ||
36 | #include <linux/pci.h> | ||
37 | |||
38 | #include <asm/pgtable.h> | ||
39 | #include <asm/gcc_intrin.h> | ||
40 | #include <asm/pal.h> | ||
41 | #include <asm/cacheflush.h> | ||
42 | #include <asm/div64.h> | ||
43 | #include <asm/tlb.h> | ||
44 | #include <asm/elf.h> | ||
45 | #include <asm/sn/addrs.h> | ||
46 | #include <asm/sn/clksupport.h> | ||
47 | #include <asm/sn/shub_mmr.h> | ||
48 | |||
49 | #include "misc.h" | ||
50 | #include "vti.h" | ||
51 | #include "iodev.h" | ||
52 | #include "ioapic.h" | ||
53 | #include "lapic.h" | ||
54 | #include "irq.h" | ||
55 | |||
56 | static unsigned long kvm_vmm_base; | ||
57 | static unsigned long kvm_vsa_base; | ||
58 | static unsigned long kvm_vm_buffer; | ||
59 | static unsigned long kvm_vm_buffer_size; | ||
60 | unsigned long kvm_vmm_gp; | ||
61 | |||
62 | static long vp_env_info; | ||
63 | |||
64 | static struct kvm_vmm_info *kvm_vmm_info; | ||
65 | |||
66 | static DEFINE_PER_CPU(struct kvm_vcpu *, last_vcpu); | ||
67 | |||
68 | struct kvm_stats_debugfs_item debugfs_entries[] = { | ||
69 | { NULL } | ||
70 | }; | ||
71 | |||
72 | static unsigned long kvm_get_itc(struct kvm_vcpu *vcpu) | ||
73 | { | ||
74 | #if defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC) | ||
75 | if (vcpu->kvm->arch.is_sn2) | ||
76 | return rtc_time(); | ||
77 | else | ||
78 | #endif | ||
79 | return ia64_getreg(_IA64_REG_AR_ITC); | ||
80 | } | ||
81 | |||
82 | static void kvm_flush_icache(unsigned long start, unsigned long len) | ||
83 | { | ||
84 | int l; | ||
85 | |||
86 | for (l = 0; l < (len + 32); l += 32) | ||
87 | ia64_fc((void *)(start + l)); | ||
88 | |||
89 | ia64_sync_i(); | ||
90 | ia64_srlz_i(); | ||
91 | } | ||
92 | |||
93 | static void kvm_flush_tlb_all(void) | ||
94 | { | ||
95 | unsigned long i, j, count0, count1, stride0, stride1, addr; | ||
96 | long flags; | ||
97 | |||
98 | addr = local_cpu_data->ptce_base; | ||
99 | count0 = local_cpu_data->ptce_count[0]; | ||
100 | count1 = local_cpu_data->ptce_count[1]; | ||
101 | stride0 = local_cpu_data->ptce_stride[0]; | ||
102 | stride1 = local_cpu_data->ptce_stride[1]; | ||
103 | |||
104 | local_irq_save(flags); | ||
105 | for (i = 0; i < count0; ++i) { | ||
106 | for (j = 0; j < count1; ++j) { | ||
107 | ia64_ptce(addr); | ||
108 | addr += stride1; | ||
109 | } | ||
110 | addr += stride0; | ||
111 | } | ||
112 | local_irq_restore(flags); | ||
113 | ia64_srlz_i(); /* srlz.i implies srlz.d */ | ||
114 | } | ||
115 | |||
116 | long ia64_pal_vp_create(u64 *vpd, u64 *host_iva, u64 *opt_handler) | ||
117 | { | ||
118 | struct ia64_pal_retval iprv; | ||
119 | |||
120 | PAL_CALL_STK(iprv, PAL_VP_CREATE, (u64)vpd, (u64)host_iva, | ||
121 | (u64)opt_handler); | ||
122 | |||
123 | return iprv.status; | ||
124 | } | ||
125 | |||
126 | static DEFINE_SPINLOCK(vp_lock); | ||
127 | |||
128 | int kvm_arch_hardware_enable(void) | ||
129 | { | ||
130 | long status; | ||
131 | long tmp_base; | ||
132 | unsigned long pte; | ||
133 | unsigned long saved_psr; | ||
134 | int slot; | ||
135 | |||
136 | pte = pte_val(mk_pte_phys(__pa(kvm_vmm_base), PAGE_KERNEL)); | ||
137 | local_irq_save(saved_psr); | ||
138 | slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT); | ||
139 | local_irq_restore(saved_psr); | ||
140 | if (slot < 0) | ||
141 | return -EINVAL; | ||
142 | |||
143 | spin_lock(&vp_lock); | ||
144 | status = ia64_pal_vp_init_env(kvm_vsa_base ? | ||
145 | VP_INIT_ENV : VP_INIT_ENV_INITALIZE, | ||
146 | __pa(kvm_vm_buffer), KVM_VM_BUFFER_BASE, &tmp_base); | ||
147 | if (status != 0) { | ||
148 | spin_unlock(&vp_lock); | ||
149 | printk(KERN_WARNING"kvm: Failed to Enable VT Support!!!!\n"); | ||
150 | return -EINVAL; | ||
151 | } | ||
152 | |||
153 | if (!kvm_vsa_base) { | ||
154 | kvm_vsa_base = tmp_base; | ||
155 | printk(KERN_INFO"kvm: kvm_vsa_base:0x%lx\n", kvm_vsa_base); | ||
156 | } | ||
157 | spin_unlock(&vp_lock); | ||
158 | ia64_ptr_entry(0x3, slot); | ||
159 | |||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | void kvm_arch_hardware_disable(void) | ||
164 | { | ||
165 | |||
166 | long status; | ||
167 | int slot; | ||
168 | unsigned long pte; | ||
169 | unsigned long saved_psr; | ||
170 | unsigned long host_iva = ia64_getreg(_IA64_REG_CR_IVA); | ||
171 | |||
172 | pte = pte_val(mk_pte_phys(__pa(kvm_vmm_base), | ||
173 | PAGE_KERNEL)); | ||
174 | |||
175 | local_irq_save(saved_psr); | ||
176 | slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT); | ||
177 | local_irq_restore(saved_psr); | ||
178 | if (slot < 0) | ||
179 | return; | ||
180 | |||
181 | status = ia64_pal_vp_exit_env(host_iva); | ||
182 | if (status) | ||
183 | printk(KERN_DEBUG"kvm: Failed to disable VT support! :%ld\n", | ||
184 | status); | ||
185 | ia64_ptr_entry(0x3, slot); | ||
186 | } | ||
187 | |||
188 | void kvm_arch_check_processor_compat(void *rtn) | ||
189 | { | ||
190 | *(int *)rtn = 0; | ||
191 | } | ||
192 | |||
193 | int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) | ||
194 | { | ||
195 | |||
196 | int r; | ||
197 | |||
198 | switch (ext) { | ||
199 | case KVM_CAP_IRQCHIP: | ||
200 | case KVM_CAP_MP_STATE: | ||
201 | case KVM_CAP_IRQ_INJECT_STATUS: | ||
202 | case KVM_CAP_IOAPIC_POLARITY_IGNORED: | ||
203 | r = 1; | ||
204 | break; | ||
205 | case KVM_CAP_COALESCED_MMIO: | ||
206 | r = KVM_COALESCED_MMIO_PAGE_OFFSET; | ||
207 | break; | ||
208 | #ifdef CONFIG_KVM_DEVICE_ASSIGNMENT | ||
209 | case KVM_CAP_IOMMU: | ||
210 | r = iommu_present(&pci_bus_type); | ||
211 | break; | ||
212 | #endif | ||
213 | default: | ||
214 | r = 0; | ||
215 | } | ||
216 | return r; | ||
217 | |||
218 | } | ||
219 | |||
220 | static int handle_vm_error(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | ||
221 | { | ||
222 | kvm_run->exit_reason = KVM_EXIT_UNKNOWN; | ||
223 | kvm_run->hw.hardware_exit_reason = 1; | ||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | ||
228 | { | ||
229 | struct kvm_mmio_req *p; | ||
230 | struct kvm_io_device *mmio_dev; | ||
231 | int r; | ||
232 | |||
233 | p = kvm_get_vcpu_ioreq(vcpu); | ||
234 | |||
235 | if ((p->addr & PAGE_MASK) == IOAPIC_DEFAULT_BASE_ADDRESS) | ||
236 | goto mmio; | ||
237 | vcpu->mmio_needed = 1; | ||
238 | vcpu->mmio_fragments[0].gpa = kvm_run->mmio.phys_addr = p->addr; | ||
239 | vcpu->mmio_fragments[0].len = kvm_run->mmio.len = p->size; | ||
240 | vcpu->mmio_is_write = kvm_run->mmio.is_write = !p->dir; | ||
241 | |||
242 | if (vcpu->mmio_is_write) | ||
243 | memcpy(vcpu->arch.mmio_data, &p->data, p->size); | ||
244 | memcpy(kvm_run->mmio.data, &p->data, p->size); | ||
245 | kvm_run->exit_reason = KVM_EXIT_MMIO; | ||
246 | return 0; | ||
247 | mmio: | ||
248 | if (p->dir) | ||
249 | r = kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, p->addr, | ||
250 | p->size, &p->data); | ||
251 | else | ||
252 | r = kvm_io_bus_write(vcpu->kvm, KVM_MMIO_BUS, p->addr, | ||
253 | p->size, &p->data); | ||
254 | if (r) | ||
255 | printk(KERN_ERR"kvm: No iodevice found! addr:%lx\n", p->addr); | ||
256 | p->state = STATE_IORESP_READY; | ||
257 | |||
258 | return 1; | ||
259 | } | ||
260 | |||
261 | static int handle_pal_call(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | ||
262 | { | ||
263 | struct exit_ctl_data *p; | ||
264 | |||
265 | p = kvm_get_exit_data(vcpu); | ||
266 | |||
267 | if (p->exit_reason == EXIT_REASON_PAL_CALL) | ||
268 | return kvm_pal_emul(vcpu, kvm_run); | ||
269 | else { | ||
270 | kvm_run->exit_reason = KVM_EXIT_UNKNOWN; | ||
271 | kvm_run->hw.hardware_exit_reason = 2; | ||
272 | return 0; | ||
273 | } | ||
274 | } | ||
275 | |||
276 | static int handle_sal_call(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | ||
277 | { | ||
278 | struct exit_ctl_data *p; | ||
279 | |||
280 | p = kvm_get_exit_data(vcpu); | ||
281 | |||
282 | if (p->exit_reason == EXIT_REASON_SAL_CALL) { | ||
283 | kvm_sal_emul(vcpu); | ||
284 | return 1; | ||
285 | } else { | ||
286 | kvm_run->exit_reason = KVM_EXIT_UNKNOWN; | ||
287 | kvm_run->hw.hardware_exit_reason = 3; | ||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | } | ||
292 | |||
293 | static int __apic_accept_irq(struct kvm_vcpu *vcpu, uint64_t vector) | ||
294 | { | ||
295 | struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd); | ||
296 | |||
297 | if (!test_and_set_bit(vector, &vpd->irr[0])) { | ||
298 | vcpu->arch.irq_new_pending = 1; | ||
299 | kvm_vcpu_kick(vcpu); | ||
300 | return 1; | ||
301 | } | ||
302 | return 0; | ||
303 | } | ||
304 | |||
305 | /* | ||
306 | * offset: address offset to IPI space. | ||
307 | * value: deliver value. | ||
308 | */ | ||
309 | static void vcpu_deliver_ipi(struct kvm_vcpu *vcpu, uint64_t dm, | ||
310 | uint64_t vector) | ||
311 | { | ||
312 | switch (dm) { | ||
313 | case SAPIC_FIXED: | ||
314 | break; | ||
315 | case SAPIC_NMI: | ||
316 | vector = 2; | ||
317 | break; | ||
318 | case SAPIC_EXTINT: | ||
319 | vector = 0; | ||
320 | break; | ||
321 | case SAPIC_INIT: | ||
322 | case SAPIC_PMI: | ||
323 | default: | ||
324 | printk(KERN_ERR"kvm: Unimplemented Deliver reserved IPI!\n"); | ||
325 | return; | ||
326 | } | ||
327 | __apic_accept_irq(vcpu, vector); | ||
328 | } | ||
329 | |||
330 | static struct kvm_vcpu *lid_to_vcpu(struct kvm *kvm, unsigned long id, | ||
331 | unsigned long eid) | ||
332 | { | ||
333 | union ia64_lid lid; | ||
334 | int i; | ||
335 | struct kvm_vcpu *vcpu; | ||
336 | |||
337 | kvm_for_each_vcpu(i, vcpu, kvm) { | ||
338 | lid.val = VCPU_LID(vcpu); | ||
339 | if (lid.id == id && lid.eid == eid) | ||
340 | return vcpu; | ||
341 | } | ||
342 | |||
343 | return NULL; | ||
344 | } | ||
345 | |||
346 | static int handle_ipi(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | ||
347 | { | ||
348 | struct exit_ctl_data *p = kvm_get_exit_data(vcpu); | ||
349 | struct kvm_vcpu *target_vcpu; | ||
350 | struct kvm_pt_regs *regs; | ||
351 | union ia64_ipi_a addr = p->u.ipi_data.addr; | ||
352 | union ia64_ipi_d data = p->u.ipi_data.data; | ||
353 | |||
354 | target_vcpu = lid_to_vcpu(vcpu->kvm, addr.id, addr.eid); | ||
355 | if (!target_vcpu) | ||
356 | return handle_vm_error(vcpu, kvm_run); | ||
357 | |||
358 | if (!target_vcpu->arch.launched) { | ||
359 | regs = vcpu_regs(target_vcpu); | ||
360 | |||
361 | regs->cr_iip = vcpu->kvm->arch.rdv_sal_data.boot_ip; | ||
362 | regs->r1 = vcpu->kvm->arch.rdv_sal_data.boot_gp; | ||
363 | |||
364 | target_vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; | ||
365 | if (waitqueue_active(&target_vcpu->wq)) | ||
366 | wake_up_interruptible(&target_vcpu->wq); | ||
367 | } else { | ||
368 | vcpu_deliver_ipi(target_vcpu, data.dm, data.vector); | ||
369 | if (target_vcpu != vcpu) | ||
370 | kvm_vcpu_kick(target_vcpu); | ||
371 | } | ||
372 | |||
373 | return 1; | ||
374 | } | ||
375 | |||
376 | struct call_data { | ||
377 | struct kvm_ptc_g ptc_g_data; | ||
378 | struct kvm_vcpu *vcpu; | ||
379 | }; | ||
380 | |||
381 | static void vcpu_global_purge(void *info) | ||
382 | { | ||
383 | struct call_data *p = (struct call_data *)info; | ||
384 | struct kvm_vcpu *vcpu = p->vcpu; | ||
385 | |||
386 | if (test_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests)) | ||
387 | return; | ||
388 | |||
389 | set_bit(KVM_REQ_PTC_G, &vcpu->requests); | ||
390 | if (vcpu->arch.ptc_g_count < MAX_PTC_G_NUM) { | ||
391 | vcpu->arch.ptc_g_data[vcpu->arch.ptc_g_count++] = | ||
392 | p->ptc_g_data; | ||
393 | } else { | ||
394 | clear_bit(KVM_REQ_PTC_G, &vcpu->requests); | ||
395 | vcpu->arch.ptc_g_count = 0; | ||
396 | set_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests); | ||
397 | } | ||
398 | } | ||
399 | |||
400 | static int handle_global_purge(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | ||
401 | { | ||
402 | struct exit_ctl_data *p = kvm_get_exit_data(vcpu); | ||
403 | struct kvm *kvm = vcpu->kvm; | ||
404 | struct call_data call_data; | ||
405 | int i; | ||
406 | struct kvm_vcpu *vcpui; | ||
407 | |||
408 | call_data.ptc_g_data = p->u.ptc_g_data; | ||
409 | |||
410 | kvm_for_each_vcpu(i, vcpui, kvm) { | ||
411 | if (vcpui->arch.mp_state == KVM_MP_STATE_UNINITIALIZED || | ||
412 | vcpu == vcpui) | ||
413 | continue; | ||
414 | |||
415 | if (waitqueue_active(&vcpui->wq)) | ||
416 | wake_up_interruptible(&vcpui->wq); | ||
417 | |||
418 | if (vcpui->cpu != -1) { | ||
419 | call_data.vcpu = vcpui; | ||
420 | smp_call_function_single(vcpui->cpu, | ||
421 | vcpu_global_purge, &call_data, 1); | ||
422 | } else | ||
423 | printk(KERN_WARNING"kvm: Uninit vcpu received ipi!\n"); | ||
424 | |||
425 | } | ||
426 | return 1; | ||
427 | } | ||
428 | |||
429 | static int handle_switch_rr6(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | ||
430 | { | ||
431 | return 1; | ||
432 | } | ||
433 | |||
434 | static int kvm_sn2_setup_mappings(struct kvm_vcpu *vcpu) | ||
435 | { | ||
436 | unsigned long pte, rtc_phys_addr, map_addr; | ||
437 | int slot; | ||
438 | |||
439 | map_addr = KVM_VMM_BASE + (1UL << KVM_VMM_SHIFT); | ||
440 | rtc_phys_addr = LOCAL_MMR_OFFSET | SH_RTC; | ||
441 | pte = pte_val(mk_pte_phys(rtc_phys_addr, PAGE_KERNEL_UC)); | ||
442 | slot = ia64_itr_entry(0x3, map_addr, pte, PAGE_SHIFT); | ||
443 | vcpu->arch.sn_rtc_tr_slot = slot; | ||
444 | if (slot < 0) { | ||
445 | printk(KERN_ERR "Mayday mayday! RTC mapping failed!\n"); | ||
446 | slot = 0; | ||
447 | } | ||
448 | return slot; | ||
449 | } | ||
450 | |||
451 | int kvm_emulate_halt(struct kvm_vcpu *vcpu) | ||
452 | { | ||
453 | |||
454 | ktime_t kt; | ||
455 | long itc_diff; | ||
456 | unsigned long vcpu_now_itc; | ||
457 | unsigned long expires; | ||
458 | struct hrtimer *p_ht = &vcpu->arch.hlt_timer; | ||
459 | unsigned long cyc_per_usec = local_cpu_data->cyc_per_usec; | ||
460 | struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd); | ||
461 | |||
462 | if (irqchip_in_kernel(vcpu->kvm)) { | ||
463 | |||
464 | vcpu_now_itc = kvm_get_itc(vcpu) + vcpu->arch.itc_offset; | ||
465 | |||
466 | if (time_after(vcpu_now_itc, vpd->itm)) { | ||
467 | vcpu->arch.timer_check = 1; | ||
468 | return 1; | ||
469 | } | ||
470 | itc_diff = vpd->itm - vcpu_now_itc; | ||
471 | if (itc_diff < 0) | ||
472 | itc_diff = -itc_diff; | ||
473 | |||
474 | expires = div64_u64(itc_diff, cyc_per_usec); | ||
475 | kt = ktime_set(0, 1000 * expires); | ||
476 | |||
477 | vcpu->arch.ht_active = 1; | ||
478 | hrtimer_start(p_ht, kt, HRTIMER_MODE_ABS); | ||
479 | |||
480 | vcpu->arch.mp_state = KVM_MP_STATE_HALTED; | ||
481 | kvm_vcpu_block(vcpu); | ||
482 | hrtimer_cancel(p_ht); | ||
483 | vcpu->arch.ht_active = 0; | ||
484 | |||
485 | if (test_and_clear_bit(KVM_REQ_UNHALT, &vcpu->requests) || | ||
486 | kvm_cpu_has_pending_timer(vcpu)) | ||
487 | if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED) | ||
488 | vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; | ||
489 | |||
490 | if (vcpu->arch.mp_state != KVM_MP_STATE_RUNNABLE) | ||
491 | return -EINTR; | ||
492 | return 1; | ||
493 | } else { | ||
494 | printk(KERN_ERR"kvm: Unsupported userspace halt!"); | ||
495 | return 0; | ||
496 | } | ||
497 | } | ||
498 | |||
499 | static int handle_vm_shutdown(struct kvm_vcpu *vcpu, | ||
500 | struct kvm_run *kvm_run) | ||
501 | { | ||
502 | kvm_run->exit_reason = KVM_EXIT_SHUTDOWN; | ||
503 | return 0; | ||
504 | } | ||
505 | |||
506 | static int handle_external_interrupt(struct kvm_vcpu *vcpu, | ||
507 | struct kvm_run *kvm_run) | ||
508 | { | ||
509 | return 1; | ||
510 | } | ||
511 | |||
512 | static int handle_vcpu_debug(struct kvm_vcpu *vcpu, | ||
513 | struct kvm_run *kvm_run) | ||
514 | { | ||
515 | printk("VMM: %s", vcpu->arch.log_buf); | ||
516 | return 1; | ||
517 | } | ||
518 | |||
519 | static int (*kvm_vti_exit_handlers[])(struct kvm_vcpu *vcpu, | ||
520 | struct kvm_run *kvm_run) = { | ||
521 | [EXIT_REASON_VM_PANIC] = handle_vm_error, | ||
522 | [EXIT_REASON_MMIO_INSTRUCTION] = handle_mmio, | ||
523 | [EXIT_REASON_PAL_CALL] = handle_pal_call, | ||
524 | [EXIT_REASON_SAL_CALL] = handle_sal_call, | ||
525 | [EXIT_REASON_SWITCH_RR6] = handle_switch_rr6, | ||
526 | [EXIT_REASON_VM_DESTROY] = handle_vm_shutdown, | ||
527 | [EXIT_REASON_EXTERNAL_INTERRUPT] = handle_external_interrupt, | ||
528 | [EXIT_REASON_IPI] = handle_ipi, | ||
529 | [EXIT_REASON_PTC_G] = handle_global_purge, | ||
530 | [EXIT_REASON_DEBUG] = handle_vcpu_debug, | ||
531 | |||
532 | }; | ||
533 | |||
534 | static const int kvm_vti_max_exit_handlers = | ||
535 | sizeof(kvm_vti_exit_handlers)/sizeof(*kvm_vti_exit_handlers); | ||
536 | |||
537 | static uint32_t kvm_get_exit_reason(struct kvm_vcpu *vcpu) | ||
538 | { | ||
539 | struct exit_ctl_data *p_exit_data; | ||
540 | |||
541 | p_exit_data = kvm_get_exit_data(vcpu); | ||
542 | return p_exit_data->exit_reason; | ||
543 | } | ||
544 | |||
545 | /* | ||
546 | * The guest has exited. See if we can fix it or if we need userspace | ||
547 | * assistance. | ||
548 | */ | ||
549 | static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | ||
550 | { | ||
551 | u32 exit_reason = kvm_get_exit_reason(vcpu); | ||
552 | vcpu->arch.last_exit = exit_reason; | ||
553 | |||
554 | if (exit_reason < kvm_vti_max_exit_handlers | ||
555 | && kvm_vti_exit_handlers[exit_reason]) | ||
556 | return kvm_vti_exit_handlers[exit_reason](vcpu, kvm_run); | ||
557 | else { | ||
558 | kvm_run->exit_reason = KVM_EXIT_UNKNOWN; | ||
559 | kvm_run->hw.hardware_exit_reason = exit_reason; | ||
560 | } | ||
561 | return 0; | ||
562 | } | ||
563 | |||
564 | static inline void vti_set_rr6(unsigned long rr6) | ||
565 | { | ||
566 | ia64_set_rr(RR6, rr6); | ||
567 | ia64_srlz_i(); | ||
568 | } | ||
569 | |||
570 | static int kvm_insert_vmm_mapping(struct kvm_vcpu *vcpu) | ||
571 | { | ||
572 | unsigned long pte; | ||
573 | struct kvm *kvm = vcpu->kvm; | ||
574 | int r; | ||
575 | |||
576 | /*Insert a pair of tr to map vmm*/ | ||
577 | pte = pte_val(mk_pte_phys(__pa(kvm_vmm_base), PAGE_KERNEL)); | ||
578 | r = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT); | ||
579 | if (r < 0) | ||
580 | goto out; | ||
581 | vcpu->arch.vmm_tr_slot = r; | ||
582 | /*Insert a pairt of tr to map data of vm*/ | ||
583 | pte = pte_val(mk_pte_phys(__pa(kvm->arch.vm_base), PAGE_KERNEL)); | ||
584 | r = ia64_itr_entry(0x3, KVM_VM_DATA_BASE, | ||
585 | pte, KVM_VM_DATA_SHIFT); | ||
586 | if (r < 0) | ||
587 | goto out; | ||
588 | vcpu->arch.vm_tr_slot = r; | ||
589 | |||
590 | #if defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC) | ||
591 | if (kvm->arch.is_sn2) { | ||
592 | r = kvm_sn2_setup_mappings(vcpu); | ||
593 | if (r < 0) | ||
594 | goto out; | ||
595 | } | ||
596 | #endif | ||
597 | |||
598 | r = 0; | ||
599 | out: | ||
600 | return r; | ||
601 | } | ||
602 | |||
603 | static void kvm_purge_vmm_mapping(struct kvm_vcpu *vcpu) | ||
604 | { | ||
605 | struct kvm *kvm = vcpu->kvm; | ||
606 | ia64_ptr_entry(0x3, vcpu->arch.vmm_tr_slot); | ||
607 | ia64_ptr_entry(0x3, vcpu->arch.vm_tr_slot); | ||
608 | #if defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC) | ||
609 | if (kvm->arch.is_sn2) | ||
610 | ia64_ptr_entry(0x3, vcpu->arch.sn_rtc_tr_slot); | ||
611 | #endif | ||
612 | } | ||
613 | |||
614 | static int kvm_vcpu_pre_transition(struct kvm_vcpu *vcpu) | ||
615 | { | ||
616 | unsigned long psr; | ||
617 | int r; | ||
618 | int cpu = smp_processor_id(); | ||
619 | |||
620 | if (vcpu->arch.last_run_cpu != cpu || | ||
621 | per_cpu(last_vcpu, cpu) != vcpu) { | ||
622 | per_cpu(last_vcpu, cpu) = vcpu; | ||
623 | vcpu->arch.last_run_cpu = cpu; | ||
624 | kvm_flush_tlb_all(); | ||
625 | } | ||
626 | |||
627 | vcpu->arch.host_rr6 = ia64_get_rr(RR6); | ||
628 | vti_set_rr6(vcpu->arch.vmm_rr); | ||
629 | local_irq_save(psr); | ||
630 | r = kvm_insert_vmm_mapping(vcpu); | ||
631 | local_irq_restore(psr); | ||
632 | return r; | ||
633 | } | ||
634 | |||
635 | static void kvm_vcpu_post_transition(struct kvm_vcpu *vcpu) | ||
636 | { | ||
637 | kvm_purge_vmm_mapping(vcpu); | ||
638 | vti_set_rr6(vcpu->arch.host_rr6); | ||
639 | } | ||
640 | |||
641 | static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | ||
642 | { | ||
643 | union context *host_ctx, *guest_ctx; | ||
644 | int r, idx; | ||
645 | |||
646 | idx = srcu_read_lock(&vcpu->kvm->srcu); | ||
647 | |||
648 | again: | ||
649 | if (signal_pending(current)) { | ||
650 | r = -EINTR; | ||
651 | kvm_run->exit_reason = KVM_EXIT_INTR; | ||
652 | goto out; | ||
653 | } | ||
654 | |||
655 | preempt_disable(); | ||
656 | local_irq_disable(); | ||
657 | |||
658 | /*Get host and guest context with guest address space.*/ | ||
659 | host_ctx = kvm_get_host_context(vcpu); | ||
660 | guest_ctx = kvm_get_guest_context(vcpu); | ||
661 | |||
662 | clear_bit(KVM_REQ_KICK, &vcpu->requests); | ||
663 | |||
664 | r = kvm_vcpu_pre_transition(vcpu); | ||
665 | if (r < 0) | ||
666 | goto vcpu_run_fail; | ||
667 | |||
668 | srcu_read_unlock(&vcpu->kvm->srcu, idx); | ||
669 | vcpu->mode = IN_GUEST_MODE; | ||
670 | kvm_guest_enter(); | ||
671 | |||
672 | /* | ||
673 | * Transition to the guest | ||
674 | */ | ||
675 | kvm_vmm_info->tramp_entry(host_ctx, guest_ctx); | ||
676 | |||
677 | kvm_vcpu_post_transition(vcpu); | ||
678 | |||
679 | vcpu->arch.launched = 1; | ||
680 | set_bit(KVM_REQ_KICK, &vcpu->requests); | ||
681 | local_irq_enable(); | ||
682 | |||
683 | /* | ||
684 | * We must have an instruction between local_irq_enable() and | ||
685 | * kvm_guest_exit(), so the timer interrupt isn't delayed by | ||
686 | * the interrupt shadow. The stat.exits increment will do nicely. | ||
687 | * But we need to prevent reordering, hence this barrier(): | ||
688 | */ | ||
689 | barrier(); | ||
690 | kvm_guest_exit(); | ||
691 | vcpu->mode = OUTSIDE_GUEST_MODE; | ||
692 | preempt_enable(); | ||
693 | |||
694 | idx = srcu_read_lock(&vcpu->kvm->srcu); | ||
695 | |||
696 | r = kvm_handle_exit(kvm_run, vcpu); | ||
697 | |||
698 | if (r > 0) { | ||
699 | if (!need_resched()) | ||
700 | goto again; | ||
701 | } | ||
702 | |||
703 | out: | ||
704 | srcu_read_unlock(&vcpu->kvm->srcu, idx); | ||
705 | if (r > 0) { | ||
706 | cond_resched(); | ||
707 | idx = srcu_read_lock(&vcpu->kvm->srcu); | ||
708 | goto again; | ||
709 | } | ||
710 | |||
711 | return r; | ||
712 | |||
713 | vcpu_run_fail: | ||
714 | local_irq_enable(); | ||
715 | preempt_enable(); | ||
716 | kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY; | ||
717 | goto out; | ||
718 | } | ||
719 | |||
720 | static void kvm_set_mmio_data(struct kvm_vcpu *vcpu) | ||
721 | { | ||
722 | struct kvm_mmio_req *p = kvm_get_vcpu_ioreq(vcpu); | ||
723 | |||
724 | if (!vcpu->mmio_is_write) | ||
725 | memcpy(&p->data, vcpu->arch.mmio_data, 8); | ||
726 | p->state = STATE_IORESP_READY; | ||
727 | } | ||
728 | |||
729 | int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | ||
730 | { | ||
731 | int r; | ||
732 | sigset_t sigsaved; | ||
733 | |||
734 | if (vcpu->sigset_active) | ||
735 | sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); | ||
736 | |||
737 | if (unlikely(vcpu->arch.mp_state == KVM_MP_STATE_UNINITIALIZED)) { | ||
738 | kvm_vcpu_block(vcpu); | ||
739 | clear_bit(KVM_REQ_UNHALT, &vcpu->requests); | ||
740 | r = -EAGAIN; | ||
741 | goto out; | ||
742 | } | ||
743 | |||
744 | if (vcpu->mmio_needed) { | ||
745 | memcpy(vcpu->arch.mmio_data, kvm_run->mmio.data, 8); | ||
746 | kvm_set_mmio_data(vcpu); | ||
747 | vcpu->mmio_read_completed = 1; | ||
748 | vcpu->mmio_needed = 0; | ||
749 | } | ||
750 | r = __vcpu_run(vcpu, kvm_run); | ||
751 | out: | ||
752 | if (vcpu->sigset_active) | ||
753 | sigprocmask(SIG_SETMASK, &sigsaved, NULL); | ||
754 | |||
755 | return r; | ||
756 | } | ||
757 | |||
758 | struct kvm *kvm_arch_alloc_vm(void) | ||
759 | { | ||
760 | |||
761 | struct kvm *kvm; | ||
762 | uint64_t vm_base; | ||
763 | |||
764 | BUG_ON(sizeof(struct kvm) > KVM_VM_STRUCT_SIZE); | ||
765 | |||
766 | vm_base = __get_free_pages(GFP_KERNEL, get_order(KVM_VM_DATA_SIZE)); | ||
767 | |||
768 | if (!vm_base) | ||
769 | return NULL; | ||
770 | |||
771 | memset((void *)vm_base, 0, KVM_VM_DATA_SIZE); | ||
772 | kvm = (struct kvm *)(vm_base + | ||
773 | offsetof(struct kvm_vm_data, kvm_vm_struct)); | ||
774 | kvm->arch.vm_base = vm_base; | ||
775 | printk(KERN_DEBUG"kvm: vm's data area:0x%lx\n", vm_base); | ||
776 | |||
777 | return kvm; | ||
778 | } | ||
779 | |||
780 | struct kvm_ia64_io_range { | ||
781 | unsigned long start; | ||
782 | unsigned long size; | ||
783 | unsigned long type; | ||
784 | }; | ||
785 | |||
786 | static const struct kvm_ia64_io_range io_ranges[] = { | ||
787 | {VGA_IO_START, VGA_IO_SIZE, GPFN_FRAME_BUFFER}, | ||
788 | {MMIO_START, MMIO_SIZE, GPFN_LOW_MMIO}, | ||
789 | {LEGACY_IO_START, LEGACY_IO_SIZE, GPFN_LEGACY_IO}, | ||
790 | {IO_SAPIC_START, IO_SAPIC_SIZE, GPFN_IOSAPIC}, | ||
791 | {PIB_START, PIB_SIZE, GPFN_PIB}, | ||
792 | }; | ||
793 | |||
794 | static void kvm_build_io_pmt(struct kvm *kvm) | ||
795 | { | ||
796 | unsigned long i, j; | ||
797 | |||
798 | /* Mark I/O ranges */ | ||
799 | for (i = 0; i < (sizeof(io_ranges) / sizeof(struct kvm_io_range)); | ||
800 | i++) { | ||
801 | for (j = io_ranges[i].start; | ||
802 | j < io_ranges[i].start + io_ranges[i].size; | ||
803 | j += PAGE_SIZE) | ||
804 | kvm_set_pmt_entry(kvm, j >> PAGE_SHIFT, | ||
805 | io_ranges[i].type, 0); | ||
806 | } | ||
807 | |||
808 | } | ||
809 | |||
810 | /*Use unused rids to virtualize guest rid.*/ | ||
811 | #define GUEST_PHYSICAL_RR0 0x1739 | ||
812 | #define GUEST_PHYSICAL_RR4 0x2739 | ||
813 | #define VMM_INIT_RR 0x1660 | ||
814 | |||
815 | int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | ||
816 | { | ||
817 | BUG_ON(!kvm); | ||
818 | |||
819 | if (type) | ||
820 | return -EINVAL; | ||
821 | |||
822 | kvm->arch.is_sn2 = ia64_platform_is("sn2"); | ||
823 | |||
824 | kvm->arch.metaphysical_rr0 = GUEST_PHYSICAL_RR0; | ||
825 | kvm->arch.metaphysical_rr4 = GUEST_PHYSICAL_RR4; | ||
826 | kvm->arch.vmm_init_rr = VMM_INIT_RR; | ||
827 | |||
828 | /* | ||
829 | *Fill P2M entries for MMIO/IO ranges | ||
830 | */ | ||
831 | kvm_build_io_pmt(kvm); | ||
832 | |||
833 | INIT_LIST_HEAD(&kvm->arch.assigned_dev_head); | ||
834 | |||
835 | /* Reserve bit 0 of irq_sources_bitmap for userspace irq source */ | ||
836 | set_bit(KVM_USERSPACE_IRQ_SOURCE_ID, &kvm->arch.irq_sources_bitmap); | ||
837 | |||
838 | return 0; | ||
839 | } | ||
840 | |||
841 | static int kvm_vm_ioctl_get_irqchip(struct kvm *kvm, | ||
842 | struct kvm_irqchip *chip) | ||
843 | { | ||
844 | int r; | ||
845 | |||
846 | r = 0; | ||
847 | switch (chip->chip_id) { | ||
848 | case KVM_IRQCHIP_IOAPIC: | ||
849 | r = kvm_get_ioapic(kvm, &chip->chip.ioapic); | ||
850 | break; | ||
851 | default: | ||
852 | r = -EINVAL; | ||
853 | break; | ||
854 | } | ||
855 | return r; | ||
856 | } | ||
857 | |||
858 | static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip) | ||
859 | { | ||
860 | int r; | ||
861 | |||
862 | r = 0; | ||
863 | switch (chip->chip_id) { | ||
864 | case KVM_IRQCHIP_IOAPIC: | ||
865 | r = kvm_set_ioapic(kvm, &chip->chip.ioapic); | ||
866 | break; | ||
867 | default: | ||
868 | r = -EINVAL; | ||
869 | break; | ||
870 | } | ||
871 | return r; | ||
872 | } | ||
873 | |||
874 | #define RESTORE_REGS(_x) vcpu->arch._x = regs->_x | ||
875 | |||
876 | int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | ||
877 | { | ||
878 | struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd); | ||
879 | int i; | ||
880 | |||
881 | for (i = 0; i < 16; i++) { | ||
882 | vpd->vgr[i] = regs->vpd.vgr[i]; | ||
883 | vpd->vbgr[i] = regs->vpd.vbgr[i]; | ||
884 | } | ||
885 | for (i = 0; i < 128; i++) | ||
886 | vpd->vcr[i] = regs->vpd.vcr[i]; | ||
887 | vpd->vhpi = regs->vpd.vhpi; | ||
888 | vpd->vnat = regs->vpd.vnat; | ||
889 | vpd->vbnat = regs->vpd.vbnat; | ||
890 | vpd->vpsr = regs->vpd.vpsr; | ||
891 | |||
892 | vpd->vpr = regs->vpd.vpr; | ||
893 | |||
894 | memcpy(&vcpu->arch.guest, ®s->saved_guest, sizeof(union context)); | ||
895 | |||
896 | RESTORE_REGS(mp_state); | ||
897 | RESTORE_REGS(vmm_rr); | ||
898 | memcpy(vcpu->arch.itrs, regs->itrs, sizeof(struct thash_data) * NITRS); | ||
899 | memcpy(vcpu->arch.dtrs, regs->dtrs, sizeof(struct thash_data) * NDTRS); | ||
900 | RESTORE_REGS(itr_regions); | ||
901 | RESTORE_REGS(dtr_regions); | ||
902 | RESTORE_REGS(tc_regions); | ||
903 | RESTORE_REGS(irq_check); | ||
904 | RESTORE_REGS(itc_check); | ||
905 | RESTORE_REGS(timer_check); | ||
906 | RESTORE_REGS(timer_pending); | ||
907 | RESTORE_REGS(last_itc); | ||
908 | for (i = 0; i < 8; i++) { | ||
909 | vcpu->arch.vrr[i] = regs->vrr[i]; | ||
910 | vcpu->arch.ibr[i] = regs->ibr[i]; | ||
911 | vcpu->arch.dbr[i] = regs->dbr[i]; | ||
912 | } | ||
913 | for (i = 0; i < 4; i++) | ||
914 | vcpu->arch.insvc[i] = regs->insvc[i]; | ||
915 | RESTORE_REGS(xtp); | ||
916 | RESTORE_REGS(metaphysical_rr0); | ||
917 | RESTORE_REGS(metaphysical_rr4); | ||
918 | RESTORE_REGS(metaphysical_saved_rr0); | ||
919 | RESTORE_REGS(metaphysical_saved_rr4); | ||
920 | RESTORE_REGS(fp_psr); | ||
921 | RESTORE_REGS(saved_gp); | ||
922 | |||
923 | vcpu->arch.irq_new_pending = 1; | ||
924 | vcpu->arch.itc_offset = regs->saved_itc - kvm_get_itc(vcpu); | ||
925 | set_bit(KVM_REQ_RESUME, &vcpu->requests); | ||
926 | |||
927 | return 0; | ||
928 | } | ||
929 | |||
930 | int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_event, | ||
931 | bool line_status) | ||
932 | { | ||
933 | if (!irqchip_in_kernel(kvm)) | ||
934 | return -ENXIO; | ||
935 | |||
936 | irq_event->status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, | ||
937 | irq_event->irq, irq_event->level, | ||
938 | line_status); | ||
939 | return 0; | ||
940 | } | ||
941 | |||
942 | long kvm_arch_vm_ioctl(struct file *filp, | ||
943 | unsigned int ioctl, unsigned long arg) | ||
944 | { | ||
945 | struct kvm *kvm = filp->private_data; | ||
946 | void __user *argp = (void __user *)arg; | ||
947 | int r = -ENOTTY; | ||
948 | |||
949 | switch (ioctl) { | ||
950 | case KVM_CREATE_IRQCHIP: | ||
951 | r = -EFAULT; | ||
952 | r = kvm_ioapic_init(kvm); | ||
953 | if (r) | ||
954 | goto out; | ||
955 | r = kvm_setup_default_irq_routing(kvm); | ||
956 | if (r) { | ||
957 | mutex_lock(&kvm->slots_lock); | ||
958 | kvm_ioapic_destroy(kvm); | ||
959 | mutex_unlock(&kvm->slots_lock); | ||
960 | goto out; | ||
961 | } | ||
962 | break; | ||
963 | case KVM_GET_IRQCHIP: { | ||
964 | /* 0: PIC master, 1: PIC slave, 2: IOAPIC */ | ||
965 | struct kvm_irqchip chip; | ||
966 | |||
967 | r = -EFAULT; | ||
968 | if (copy_from_user(&chip, argp, sizeof chip)) | ||
969 | goto out; | ||
970 | r = -ENXIO; | ||
971 | if (!irqchip_in_kernel(kvm)) | ||
972 | goto out; | ||
973 | r = kvm_vm_ioctl_get_irqchip(kvm, &chip); | ||
974 | if (r) | ||
975 | goto out; | ||
976 | r = -EFAULT; | ||
977 | if (copy_to_user(argp, &chip, sizeof chip)) | ||
978 | goto out; | ||
979 | r = 0; | ||
980 | break; | ||
981 | } | ||
982 | case KVM_SET_IRQCHIP: { | ||
983 | /* 0: PIC master, 1: PIC slave, 2: IOAPIC */ | ||
984 | struct kvm_irqchip chip; | ||
985 | |||
986 | r = -EFAULT; | ||
987 | if (copy_from_user(&chip, argp, sizeof chip)) | ||
988 | goto out; | ||
989 | r = -ENXIO; | ||
990 | if (!irqchip_in_kernel(kvm)) | ||
991 | goto out; | ||
992 | r = kvm_vm_ioctl_set_irqchip(kvm, &chip); | ||
993 | if (r) | ||
994 | goto out; | ||
995 | r = 0; | ||
996 | break; | ||
997 | } | ||
998 | default: | ||
999 | ; | ||
1000 | } | ||
1001 | out: | ||
1002 | return r; | ||
1003 | } | ||
1004 | |||
1005 | int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, | ||
1006 | struct kvm_sregs *sregs) | ||
1007 | { | ||
1008 | return -EINVAL; | ||
1009 | } | ||
1010 | |||
1011 | int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, | ||
1012 | struct kvm_sregs *sregs) | ||
1013 | { | ||
1014 | return -EINVAL; | ||
1015 | |||
1016 | } | ||
1017 | int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, | ||
1018 | struct kvm_translation *tr) | ||
1019 | { | ||
1020 | |||
1021 | return -EINVAL; | ||
1022 | } | ||
1023 | |||
1024 | static int kvm_alloc_vmm_area(void) | ||
1025 | { | ||
1026 | if (!kvm_vmm_base && (kvm_vm_buffer_size < KVM_VM_BUFFER_SIZE)) { | ||
1027 | kvm_vmm_base = __get_free_pages(GFP_KERNEL, | ||
1028 | get_order(KVM_VMM_SIZE)); | ||
1029 | if (!kvm_vmm_base) | ||
1030 | return -ENOMEM; | ||
1031 | |||
1032 | memset((void *)kvm_vmm_base, 0, KVM_VMM_SIZE); | ||
1033 | kvm_vm_buffer = kvm_vmm_base + VMM_SIZE; | ||
1034 | |||
1035 | printk(KERN_DEBUG"kvm:VMM's Base Addr:0x%lx, vm_buffer:0x%lx\n", | ||
1036 | kvm_vmm_base, kvm_vm_buffer); | ||
1037 | } | ||
1038 | |||
1039 | return 0; | ||
1040 | } | ||
1041 | |||
1042 | static void kvm_free_vmm_area(void) | ||
1043 | { | ||
1044 | if (kvm_vmm_base) { | ||
1045 | /*Zero this area before free to avoid bits leak!!*/ | ||
1046 | memset((void *)kvm_vmm_base, 0, KVM_VMM_SIZE); | ||
1047 | free_pages(kvm_vmm_base, get_order(KVM_VMM_SIZE)); | ||
1048 | kvm_vmm_base = 0; | ||
1049 | kvm_vm_buffer = 0; | ||
1050 | kvm_vsa_base = 0; | ||
1051 | } | ||
1052 | } | ||
1053 | |||
1054 | static int vti_init_vpd(struct kvm_vcpu *vcpu) | ||
1055 | { | ||
1056 | int i; | ||
1057 | union cpuid3_t cpuid3; | ||
1058 | struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd); | ||
1059 | |||
1060 | if (IS_ERR(vpd)) | ||
1061 | return PTR_ERR(vpd); | ||
1062 | |||
1063 | /* CPUID init */ | ||
1064 | for (i = 0; i < 5; i++) | ||
1065 | vpd->vcpuid[i] = ia64_get_cpuid(i); | ||
1066 | |||
1067 | /* Limit the CPUID number to 5 */ | ||
1068 | cpuid3.value = vpd->vcpuid[3]; | ||
1069 | cpuid3.number = 4; /* 5 - 1 */ | ||
1070 | vpd->vcpuid[3] = cpuid3.value; | ||
1071 | |||
1072 | /*Set vac and vdc fields*/ | ||
1073 | vpd->vac.a_from_int_cr = 1; | ||
1074 | vpd->vac.a_to_int_cr = 1; | ||
1075 | vpd->vac.a_from_psr = 1; | ||
1076 | vpd->vac.a_from_cpuid = 1; | ||
1077 | vpd->vac.a_cover = 1; | ||
1078 | vpd->vac.a_bsw = 1; | ||
1079 | vpd->vac.a_int = 1; | ||
1080 | vpd->vdc.d_vmsw = 1; | ||
1081 | |||
1082 | /*Set virtual buffer*/ | ||
1083 | vpd->virt_env_vaddr = KVM_VM_BUFFER_BASE; | ||
1084 | |||
1085 | return 0; | ||
1086 | } | ||
1087 | |||
1088 | static int vti_create_vp(struct kvm_vcpu *vcpu) | ||
1089 | { | ||
1090 | long ret; | ||
1091 | struct vpd *vpd = vcpu->arch.vpd; | ||
1092 | unsigned long vmm_ivt; | ||
1093 | |||
1094 | vmm_ivt = kvm_vmm_info->vmm_ivt; | ||
1095 | |||
1096 | printk(KERN_DEBUG "kvm: vcpu:%p,ivt: 0x%lx\n", vcpu, vmm_ivt); | ||
1097 | |||
1098 | ret = ia64_pal_vp_create((u64 *)vpd, (u64 *)vmm_ivt, 0); | ||
1099 | |||
1100 | if (ret) { | ||
1101 | printk(KERN_ERR"kvm: ia64_pal_vp_create failed!\n"); | ||
1102 | return -EINVAL; | ||
1103 | } | ||
1104 | return 0; | ||
1105 | } | ||
1106 | |||
1107 | static void init_ptce_info(struct kvm_vcpu *vcpu) | ||
1108 | { | ||
1109 | ia64_ptce_info_t ptce = {0}; | ||
1110 | |||
1111 | ia64_get_ptce(&ptce); | ||
1112 | vcpu->arch.ptce_base = ptce.base; | ||
1113 | vcpu->arch.ptce_count[0] = ptce.count[0]; | ||
1114 | vcpu->arch.ptce_count[1] = ptce.count[1]; | ||
1115 | vcpu->arch.ptce_stride[0] = ptce.stride[0]; | ||
1116 | vcpu->arch.ptce_stride[1] = ptce.stride[1]; | ||
1117 | } | ||
1118 | |||
1119 | static void kvm_migrate_hlt_timer(struct kvm_vcpu *vcpu) | ||
1120 | { | ||
1121 | struct hrtimer *p_ht = &vcpu->arch.hlt_timer; | ||
1122 | |||
1123 | if (hrtimer_cancel(p_ht)) | ||
1124 | hrtimer_start_expires(p_ht, HRTIMER_MODE_ABS); | ||
1125 | } | ||
1126 | |||
1127 | static enum hrtimer_restart hlt_timer_fn(struct hrtimer *data) | ||
1128 | { | ||
1129 | struct kvm_vcpu *vcpu; | ||
1130 | wait_queue_head_t *q; | ||
1131 | |||
1132 | vcpu = container_of(data, struct kvm_vcpu, arch.hlt_timer); | ||
1133 | q = &vcpu->wq; | ||
1134 | |||
1135 | if (vcpu->arch.mp_state != KVM_MP_STATE_HALTED) | ||
1136 | goto out; | ||
1137 | |||
1138 | if (waitqueue_active(q)) | ||
1139 | wake_up_interruptible(q); | ||
1140 | |||
1141 | out: | ||
1142 | vcpu->arch.timer_fired = 1; | ||
1143 | vcpu->arch.timer_check = 1; | ||
1144 | return HRTIMER_NORESTART; | ||
1145 | } | ||
1146 | |||
1147 | #define PALE_RESET_ENTRY 0x80000000ffffffb0UL | ||
1148 | |||
1149 | bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu) | ||
1150 | { | ||
1151 | return irqchip_in_kernel(vcpu->kvm) == (vcpu->arch.apic != NULL); | ||
1152 | } | ||
1153 | |||
1154 | int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | ||
1155 | { | ||
1156 | struct kvm_vcpu *v; | ||
1157 | int r; | ||
1158 | int i; | ||
1159 | long itc_offset; | ||
1160 | struct kvm *kvm = vcpu->kvm; | ||
1161 | struct kvm_pt_regs *regs = vcpu_regs(vcpu); | ||
1162 | |||
1163 | union context *p_ctx = &vcpu->arch.guest; | ||
1164 | struct kvm_vcpu *vmm_vcpu = to_guest(vcpu->kvm, vcpu); | ||
1165 | |||
1166 | /*Init vcpu context for first run.*/ | ||
1167 | if (IS_ERR(vmm_vcpu)) | ||
1168 | return PTR_ERR(vmm_vcpu); | ||
1169 | |||
1170 | if (kvm_vcpu_is_bsp(vcpu)) { | ||
1171 | vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; | ||
1172 | |||
1173 | /*Set entry address for first run.*/ | ||
1174 | regs->cr_iip = PALE_RESET_ENTRY; | ||
1175 | |||
1176 | /*Initialize itc offset for vcpus*/ | ||
1177 | itc_offset = 0UL - kvm_get_itc(vcpu); | ||
1178 | for (i = 0; i < KVM_MAX_VCPUS; i++) { | ||
1179 | v = (struct kvm_vcpu *)((char *)vcpu + | ||
1180 | sizeof(struct kvm_vcpu_data) * i); | ||
1181 | v->arch.itc_offset = itc_offset; | ||
1182 | v->arch.last_itc = 0; | ||
1183 | } | ||
1184 | } else | ||
1185 | vcpu->arch.mp_state = KVM_MP_STATE_UNINITIALIZED; | ||
1186 | |||
1187 | r = -ENOMEM; | ||
1188 | vcpu->arch.apic = kzalloc(sizeof(struct kvm_lapic), GFP_KERNEL); | ||
1189 | if (!vcpu->arch.apic) | ||
1190 | goto out; | ||
1191 | vcpu->arch.apic->vcpu = vcpu; | ||
1192 | |||
1193 | p_ctx->gr[1] = 0; | ||
1194 | p_ctx->gr[12] = (unsigned long)((char *)vmm_vcpu + KVM_STK_OFFSET); | ||
1195 | p_ctx->gr[13] = (unsigned long)vmm_vcpu; | ||
1196 | p_ctx->psr = 0x1008522000UL; | ||
1197 | p_ctx->ar[40] = FPSR_DEFAULT; /*fpsr*/ | ||
1198 | p_ctx->caller_unat = 0; | ||
1199 | p_ctx->pr = 0x0; | ||
1200 | p_ctx->ar[36] = 0x0; /*unat*/ | ||
1201 | p_ctx->ar[19] = 0x0; /*rnat*/ | ||
1202 | p_ctx->ar[18] = (unsigned long)vmm_vcpu + | ||
1203 | ((sizeof(struct kvm_vcpu)+15) & ~15); | ||
1204 | p_ctx->ar[64] = 0x0; /*pfs*/ | ||
1205 | p_ctx->cr[0] = 0x7e04UL; | ||
1206 | p_ctx->cr[2] = (unsigned long)kvm_vmm_info->vmm_ivt; | ||
1207 | p_ctx->cr[8] = 0x3c; | ||
1208 | |||
1209 | /*Initialize region register*/ | ||
1210 | p_ctx->rr[0] = 0x30; | ||
1211 | p_ctx->rr[1] = 0x30; | ||
1212 | p_ctx->rr[2] = 0x30; | ||
1213 | p_ctx->rr[3] = 0x30; | ||
1214 | p_ctx->rr[4] = 0x30; | ||
1215 | p_ctx->rr[5] = 0x30; | ||
1216 | p_ctx->rr[7] = 0x30; | ||
1217 | |||
1218 | /*Initialize branch register 0*/ | ||
1219 | p_ctx->br[0] = *(unsigned long *)kvm_vmm_info->vmm_entry; | ||
1220 | |||
1221 | vcpu->arch.vmm_rr = kvm->arch.vmm_init_rr; | ||
1222 | vcpu->arch.metaphysical_rr0 = kvm->arch.metaphysical_rr0; | ||
1223 | vcpu->arch.metaphysical_rr4 = kvm->arch.metaphysical_rr4; | ||
1224 | |||
1225 | hrtimer_init(&vcpu->arch.hlt_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); | ||
1226 | vcpu->arch.hlt_timer.function = hlt_timer_fn; | ||
1227 | |||
1228 | vcpu->arch.last_run_cpu = -1; | ||
1229 | vcpu->arch.vpd = (struct vpd *)VPD_BASE(vcpu->vcpu_id); | ||
1230 | vcpu->arch.vsa_base = kvm_vsa_base; | ||
1231 | vcpu->arch.__gp = kvm_vmm_gp; | ||
1232 | vcpu->arch.dirty_log_lock_pa = __pa(&kvm->arch.dirty_log_lock); | ||
1233 | vcpu->arch.vhpt.hash = (struct thash_data *)VHPT_BASE(vcpu->vcpu_id); | ||
1234 | vcpu->arch.vtlb.hash = (struct thash_data *)VTLB_BASE(vcpu->vcpu_id); | ||
1235 | init_ptce_info(vcpu); | ||
1236 | |||
1237 | r = 0; | ||
1238 | out: | ||
1239 | return r; | ||
1240 | } | ||
1241 | |||
1242 | static int vti_vcpu_setup(struct kvm_vcpu *vcpu, int id) | ||
1243 | { | ||
1244 | unsigned long psr; | ||
1245 | int r; | ||
1246 | |||
1247 | local_irq_save(psr); | ||
1248 | r = kvm_insert_vmm_mapping(vcpu); | ||
1249 | local_irq_restore(psr); | ||
1250 | if (r) | ||
1251 | goto fail; | ||
1252 | r = kvm_vcpu_init(vcpu, vcpu->kvm, id); | ||
1253 | if (r) | ||
1254 | goto fail; | ||
1255 | |||
1256 | r = vti_init_vpd(vcpu); | ||
1257 | if (r) { | ||
1258 | printk(KERN_DEBUG"kvm: vpd init error!!\n"); | ||
1259 | goto uninit; | ||
1260 | } | ||
1261 | |||
1262 | r = vti_create_vp(vcpu); | ||
1263 | if (r) | ||
1264 | goto uninit; | ||
1265 | |||
1266 | kvm_purge_vmm_mapping(vcpu); | ||
1267 | |||
1268 | return 0; | ||
1269 | uninit: | ||
1270 | kvm_vcpu_uninit(vcpu); | ||
1271 | fail: | ||
1272 | return r; | ||
1273 | } | ||
1274 | |||
1275 | struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, | ||
1276 | unsigned int id) | ||
1277 | { | ||
1278 | struct kvm_vcpu *vcpu; | ||
1279 | unsigned long vm_base = kvm->arch.vm_base; | ||
1280 | int r; | ||
1281 | int cpu; | ||
1282 | |||
1283 | BUG_ON(sizeof(struct kvm_vcpu) > VCPU_STRUCT_SIZE/2); | ||
1284 | |||
1285 | r = -EINVAL; | ||
1286 | if (id >= KVM_MAX_VCPUS) { | ||
1287 | printk(KERN_ERR"kvm: Can't configure vcpus > %ld", | ||
1288 | KVM_MAX_VCPUS); | ||
1289 | goto fail; | ||
1290 | } | ||
1291 | |||
1292 | r = -ENOMEM; | ||
1293 | if (!vm_base) { | ||
1294 | printk(KERN_ERR"kvm: Create vcpu[%d] error!\n", id); | ||
1295 | goto fail; | ||
1296 | } | ||
1297 | vcpu = (struct kvm_vcpu *)(vm_base + offsetof(struct kvm_vm_data, | ||
1298 | vcpu_data[id].vcpu_struct)); | ||
1299 | vcpu->kvm = kvm; | ||
1300 | |||
1301 | cpu = get_cpu(); | ||
1302 | r = vti_vcpu_setup(vcpu, id); | ||
1303 | put_cpu(); | ||
1304 | |||
1305 | if (r) { | ||
1306 | printk(KERN_DEBUG"kvm: vcpu_setup error!!\n"); | ||
1307 | goto fail; | ||
1308 | } | ||
1309 | |||
1310 | return vcpu; | ||
1311 | fail: | ||
1312 | return ERR_PTR(r); | ||
1313 | } | ||
1314 | |||
1315 | int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | ||
1316 | { | ||
1317 | return 0; | ||
1318 | } | ||
1319 | |||
1320 | int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) | ||
1321 | { | ||
1322 | return 0; | ||
1323 | } | ||
1324 | |||
1325 | int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) | ||
1326 | { | ||
1327 | return -EINVAL; | ||
1328 | } | ||
1329 | |||
1330 | int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) | ||
1331 | { | ||
1332 | return -EINVAL; | ||
1333 | } | ||
1334 | |||
1335 | int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, | ||
1336 | struct kvm_guest_debug *dbg) | ||
1337 | { | ||
1338 | return -EINVAL; | ||
1339 | } | ||
1340 | |||
1341 | void kvm_arch_free_vm(struct kvm *kvm) | ||
1342 | { | ||
1343 | unsigned long vm_base = kvm->arch.vm_base; | ||
1344 | |||
1345 | if (vm_base) { | ||
1346 | memset((void *)vm_base, 0, KVM_VM_DATA_SIZE); | ||
1347 | free_pages(vm_base, get_order(KVM_VM_DATA_SIZE)); | ||
1348 | } | ||
1349 | |||
1350 | } | ||
1351 | |||
1352 | static void kvm_release_vm_pages(struct kvm *kvm) | ||
1353 | { | ||
1354 | struct kvm_memslots *slots; | ||
1355 | struct kvm_memory_slot *memslot; | ||
1356 | int j; | ||
1357 | |||
1358 | slots = kvm_memslots(kvm); | ||
1359 | kvm_for_each_memslot(memslot, slots) { | ||
1360 | for (j = 0; j < memslot->npages; j++) { | ||
1361 | if (memslot->rmap[j]) | ||
1362 | put_page((struct page *)memslot->rmap[j]); | ||
1363 | } | ||
1364 | } | ||
1365 | } | ||
1366 | |||
1367 | void kvm_arch_destroy_vm(struct kvm *kvm) | ||
1368 | { | ||
1369 | kvm_iommu_unmap_guest(kvm); | ||
1370 | kvm_free_all_assigned_devices(kvm); | ||
1371 | kfree(kvm->arch.vioapic); | ||
1372 | kvm_release_vm_pages(kvm); | ||
1373 | } | ||
1374 | |||
1375 | void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | ||
1376 | { | ||
1377 | if (cpu != vcpu->cpu) { | ||
1378 | vcpu->cpu = cpu; | ||
1379 | if (vcpu->arch.ht_active) | ||
1380 | kvm_migrate_hlt_timer(vcpu); | ||
1381 | } | ||
1382 | } | ||
1383 | |||
1384 | #define SAVE_REGS(_x) regs->_x = vcpu->arch._x | ||
1385 | |||
1386 | int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | ||
1387 | { | ||
1388 | struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd); | ||
1389 | int i; | ||
1390 | |||
1391 | vcpu_load(vcpu); | ||
1392 | |||
1393 | for (i = 0; i < 16; i++) { | ||
1394 | regs->vpd.vgr[i] = vpd->vgr[i]; | ||
1395 | regs->vpd.vbgr[i] = vpd->vbgr[i]; | ||
1396 | } | ||
1397 | for (i = 0; i < 128; i++) | ||
1398 | regs->vpd.vcr[i] = vpd->vcr[i]; | ||
1399 | regs->vpd.vhpi = vpd->vhpi; | ||
1400 | regs->vpd.vnat = vpd->vnat; | ||
1401 | regs->vpd.vbnat = vpd->vbnat; | ||
1402 | regs->vpd.vpsr = vpd->vpsr; | ||
1403 | regs->vpd.vpr = vpd->vpr; | ||
1404 | |||
1405 | memcpy(®s->saved_guest, &vcpu->arch.guest, sizeof(union context)); | ||
1406 | |||
1407 | SAVE_REGS(mp_state); | ||
1408 | SAVE_REGS(vmm_rr); | ||
1409 | memcpy(regs->itrs, vcpu->arch.itrs, sizeof(struct thash_data) * NITRS); | ||
1410 | memcpy(regs->dtrs, vcpu->arch.dtrs, sizeof(struct thash_data) * NDTRS); | ||
1411 | SAVE_REGS(itr_regions); | ||
1412 | SAVE_REGS(dtr_regions); | ||
1413 | SAVE_REGS(tc_regions); | ||
1414 | SAVE_REGS(irq_check); | ||
1415 | SAVE_REGS(itc_check); | ||
1416 | SAVE_REGS(timer_check); | ||
1417 | SAVE_REGS(timer_pending); | ||
1418 | SAVE_REGS(last_itc); | ||
1419 | for (i = 0; i < 8; i++) { | ||
1420 | regs->vrr[i] = vcpu->arch.vrr[i]; | ||
1421 | regs->ibr[i] = vcpu->arch.ibr[i]; | ||
1422 | regs->dbr[i] = vcpu->arch.dbr[i]; | ||
1423 | } | ||
1424 | for (i = 0; i < 4; i++) | ||
1425 | regs->insvc[i] = vcpu->arch.insvc[i]; | ||
1426 | regs->saved_itc = vcpu->arch.itc_offset + kvm_get_itc(vcpu); | ||
1427 | SAVE_REGS(xtp); | ||
1428 | SAVE_REGS(metaphysical_rr0); | ||
1429 | SAVE_REGS(metaphysical_rr4); | ||
1430 | SAVE_REGS(metaphysical_saved_rr0); | ||
1431 | SAVE_REGS(metaphysical_saved_rr4); | ||
1432 | SAVE_REGS(fp_psr); | ||
1433 | SAVE_REGS(saved_gp); | ||
1434 | |||
1435 | vcpu_put(vcpu); | ||
1436 | return 0; | ||
1437 | } | ||
1438 | |||
1439 | int kvm_arch_vcpu_ioctl_get_stack(struct kvm_vcpu *vcpu, | ||
1440 | struct kvm_ia64_vcpu_stack *stack) | ||
1441 | { | ||
1442 | memcpy(stack, vcpu, sizeof(struct kvm_ia64_vcpu_stack)); | ||
1443 | return 0; | ||
1444 | } | ||
1445 | |||
1446 | int kvm_arch_vcpu_ioctl_set_stack(struct kvm_vcpu *vcpu, | ||
1447 | struct kvm_ia64_vcpu_stack *stack) | ||
1448 | { | ||
1449 | memcpy(vcpu + 1, &stack->stack[0] + sizeof(struct kvm_vcpu), | ||
1450 | sizeof(struct kvm_ia64_vcpu_stack) - sizeof(struct kvm_vcpu)); | ||
1451 | |||
1452 | vcpu->arch.exit_data = ((struct kvm_vcpu *)stack)->arch.exit_data; | ||
1453 | return 0; | ||
1454 | } | ||
1455 | |||
1456 | void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) | ||
1457 | { | ||
1458 | |||
1459 | hrtimer_cancel(&vcpu->arch.hlt_timer); | ||
1460 | kfree(vcpu->arch.apic); | ||
1461 | } | ||
1462 | |||
1463 | long kvm_arch_vcpu_ioctl(struct file *filp, | ||
1464 | unsigned int ioctl, unsigned long arg) | ||
1465 | { | ||
1466 | struct kvm_vcpu *vcpu = filp->private_data; | ||
1467 | void __user *argp = (void __user *)arg; | ||
1468 | struct kvm_ia64_vcpu_stack *stack = NULL; | ||
1469 | long r; | ||
1470 | |||
1471 | switch (ioctl) { | ||
1472 | case KVM_IA64_VCPU_GET_STACK: { | ||
1473 | struct kvm_ia64_vcpu_stack __user *user_stack; | ||
1474 | void __user *first_p = argp; | ||
1475 | |||
1476 | r = -EFAULT; | ||
1477 | if (copy_from_user(&user_stack, first_p, sizeof(void *))) | ||
1478 | goto out; | ||
1479 | |||
1480 | if (!access_ok(VERIFY_WRITE, user_stack, | ||
1481 | sizeof(struct kvm_ia64_vcpu_stack))) { | ||
1482 | printk(KERN_INFO "KVM_IA64_VCPU_GET_STACK: " | ||
1483 | "Illegal user destination address for stack\n"); | ||
1484 | goto out; | ||
1485 | } | ||
1486 | stack = kzalloc(sizeof(struct kvm_ia64_vcpu_stack), GFP_KERNEL); | ||
1487 | if (!stack) { | ||
1488 | r = -ENOMEM; | ||
1489 | goto out; | ||
1490 | } | ||
1491 | |||
1492 | r = kvm_arch_vcpu_ioctl_get_stack(vcpu, stack); | ||
1493 | if (r) | ||
1494 | goto out; | ||
1495 | |||
1496 | if (copy_to_user(user_stack, stack, | ||
1497 | sizeof(struct kvm_ia64_vcpu_stack))) { | ||
1498 | r = -EFAULT; | ||
1499 | goto out; | ||
1500 | } | ||
1501 | |||
1502 | break; | ||
1503 | } | ||
1504 | case KVM_IA64_VCPU_SET_STACK: { | ||
1505 | struct kvm_ia64_vcpu_stack __user *user_stack; | ||
1506 | void __user *first_p = argp; | ||
1507 | |||
1508 | r = -EFAULT; | ||
1509 | if (copy_from_user(&user_stack, first_p, sizeof(void *))) | ||
1510 | goto out; | ||
1511 | |||
1512 | if (!access_ok(VERIFY_READ, user_stack, | ||
1513 | sizeof(struct kvm_ia64_vcpu_stack))) { | ||
1514 | printk(KERN_INFO "KVM_IA64_VCPU_SET_STACK: " | ||
1515 | "Illegal user address for stack\n"); | ||
1516 | goto out; | ||
1517 | } | ||
1518 | stack = kmalloc(sizeof(struct kvm_ia64_vcpu_stack), GFP_KERNEL); | ||
1519 | if (!stack) { | ||
1520 | r = -ENOMEM; | ||
1521 | goto out; | ||
1522 | } | ||
1523 | if (copy_from_user(stack, user_stack, | ||
1524 | sizeof(struct kvm_ia64_vcpu_stack))) | ||
1525 | goto out; | ||
1526 | |||
1527 | r = kvm_arch_vcpu_ioctl_set_stack(vcpu, stack); | ||
1528 | break; | ||
1529 | } | ||
1530 | |||
1531 | default: | ||
1532 | r = -EINVAL; | ||
1533 | } | ||
1534 | |||
1535 | out: | ||
1536 | kfree(stack); | ||
1537 | return r; | ||
1538 | } | ||
1539 | |||
1540 | int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf) | ||
1541 | { | ||
1542 | return VM_FAULT_SIGBUS; | ||
1543 | } | ||
1544 | |||
1545 | int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, | ||
1546 | unsigned long npages) | ||
1547 | { | ||
1548 | return 0; | ||
1549 | } | ||
1550 | |||
1551 | int kvm_arch_prepare_memory_region(struct kvm *kvm, | ||
1552 | struct kvm_memory_slot *memslot, | ||
1553 | struct kvm_userspace_memory_region *mem, | ||
1554 | enum kvm_mr_change change) | ||
1555 | { | ||
1556 | unsigned long i; | ||
1557 | unsigned long pfn; | ||
1558 | int npages = memslot->npages; | ||
1559 | unsigned long base_gfn = memslot->base_gfn; | ||
1560 | |||
1561 | if (base_gfn + npages > (KVM_MAX_MEM_SIZE >> PAGE_SHIFT)) | ||
1562 | return -ENOMEM; | ||
1563 | |||
1564 | for (i = 0; i < npages; i++) { | ||
1565 | pfn = gfn_to_pfn(kvm, base_gfn + i); | ||
1566 | if (!kvm_is_reserved_pfn(pfn)) { | ||
1567 | kvm_set_pmt_entry(kvm, base_gfn + i, | ||
1568 | pfn << PAGE_SHIFT, | ||
1569 | _PAGE_AR_RWX | _PAGE_MA_WB); | ||
1570 | memslot->rmap[i] = (unsigned long)pfn_to_page(pfn); | ||
1571 | } else { | ||
1572 | kvm_set_pmt_entry(kvm, base_gfn + i, | ||
1573 | GPFN_PHYS_MMIO | (pfn << PAGE_SHIFT), | ||
1574 | _PAGE_MA_UC); | ||
1575 | memslot->rmap[i] = 0; | ||
1576 | } | ||
1577 | } | ||
1578 | |||
1579 | return 0; | ||
1580 | } | ||
1581 | |||
1582 | void kvm_arch_flush_shadow_all(struct kvm *kvm) | ||
1583 | { | ||
1584 | kvm_flush_remote_tlbs(kvm); | ||
1585 | } | ||
1586 | |||
1587 | void kvm_arch_flush_shadow_memslot(struct kvm *kvm, | ||
1588 | struct kvm_memory_slot *slot) | ||
1589 | { | ||
1590 | kvm_arch_flush_shadow_all(); | ||
1591 | } | ||
1592 | |||
1593 | long kvm_arch_dev_ioctl(struct file *filp, | ||
1594 | unsigned int ioctl, unsigned long arg) | ||
1595 | { | ||
1596 | return -EINVAL; | ||
1597 | } | ||
1598 | |||
1599 | void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) | ||
1600 | { | ||
1601 | kvm_vcpu_uninit(vcpu); | ||
1602 | } | ||
1603 | |||
1604 | static int vti_cpu_has_kvm_support(void) | ||
1605 | { | ||
1606 | long avail = 1, status = 1, control = 1; | ||
1607 | long ret; | ||
1608 | |||
1609 | ret = ia64_pal_proc_get_features(&avail, &status, &control, 0); | ||
1610 | if (ret) | ||
1611 | goto out; | ||
1612 | |||
1613 | if (!(avail & PAL_PROC_VM_BIT)) | ||
1614 | goto out; | ||
1615 | |||
1616 | printk(KERN_DEBUG"kvm: Hardware Supports VT\n"); | ||
1617 | |||
1618 | ret = ia64_pal_vp_env_info(&kvm_vm_buffer_size, &vp_env_info); | ||
1619 | if (ret) | ||
1620 | goto out; | ||
1621 | printk(KERN_DEBUG"kvm: VM Buffer Size:0x%lx\n", kvm_vm_buffer_size); | ||
1622 | |||
1623 | if (!(vp_env_info & VP_OPCODE)) { | ||
1624 | printk(KERN_WARNING"kvm: No opcode ability on hardware, " | ||
1625 | "vm_env_info:0x%lx\n", vp_env_info); | ||
1626 | } | ||
1627 | |||
1628 | return 1; | ||
1629 | out: | ||
1630 | return 0; | ||
1631 | } | ||
1632 | |||
1633 | |||
1634 | /* | ||
1635 | * On SN2, the ITC isn't stable, so copy in fast path code to use the | ||
1636 | * SN2 RTC, replacing the ITC based default verion. | ||
1637 | */ | ||
1638 | static void kvm_patch_vmm(struct kvm_vmm_info *vmm_info, | ||
1639 | struct module *module) | ||
1640 | { | ||
1641 | unsigned long new_ar, new_ar_sn2; | ||
1642 | unsigned long module_base; | ||
1643 | |||
1644 | if (!ia64_platform_is("sn2")) | ||
1645 | return; | ||
1646 | |||
1647 | module_base = (unsigned long)module->module_core; | ||
1648 | |||
1649 | new_ar = kvm_vmm_base + vmm_info->patch_mov_ar - module_base; | ||
1650 | new_ar_sn2 = kvm_vmm_base + vmm_info->patch_mov_ar_sn2 - module_base; | ||
1651 | |||
1652 | printk(KERN_INFO "kvm: Patching ITC emulation to use SGI SN2 RTC " | ||
1653 | "as source\n"); | ||
1654 | |||
1655 | /* | ||
1656 | * Copy the SN2 version of mov_ar into place. They are both | ||
1657 | * the same size, so 6 bundles is sufficient (6 * 0x10). | ||
1658 | */ | ||
1659 | memcpy((void *)new_ar, (void *)new_ar_sn2, 0x60); | ||
1660 | } | ||
1661 | |||
1662 | static int kvm_relocate_vmm(struct kvm_vmm_info *vmm_info, | ||
1663 | struct module *module) | ||
1664 | { | ||
1665 | unsigned long module_base; | ||
1666 | unsigned long vmm_size; | ||
1667 | |||
1668 | unsigned long vmm_offset, func_offset, fdesc_offset; | ||
1669 | struct fdesc *p_fdesc; | ||
1670 | |||
1671 | BUG_ON(!module); | ||
1672 | |||
1673 | if (!kvm_vmm_base) { | ||
1674 | printk("kvm: kvm area hasn't been initialized yet!!\n"); | ||
1675 | return -EFAULT; | ||
1676 | } | ||
1677 | |||
1678 | /*Calculate new position of relocated vmm module.*/ | ||
1679 | module_base = (unsigned long)module->module_core; | ||
1680 | vmm_size = module->core_size; | ||
1681 | if (unlikely(vmm_size > KVM_VMM_SIZE)) | ||
1682 | return -EFAULT; | ||
1683 | |||
1684 | memcpy((void *)kvm_vmm_base, (void *)module_base, vmm_size); | ||
1685 | kvm_patch_vmm(vmm_info, module); | ||
1686 | kvm_flush_icache(kvm_vmm_base, vmm_size); | ||
1687 | |||
1688 | /*Recalculate kvm_vmm_info based on new VMM*/ | ||
1689 | vmm_offset = vmm_info->vmm_ivt - module_base; | ||
1690 | kvm_vmm_info->vmm_ivt = KVM_VMM_BASE + vmm_offset; | ||
1691 | printk(KERN_DEBUG"kvm: Relocated VMM's IVT Base Addr:%lx\n", | ||
1692 | kvm_vmm_info->vmm_ivt); | ||
1693 | |||
1694 | fdesc_offset = (unsigned long)vmm_info->vmm_entry - module_base; | ||
1695 | kvm_vmm_info->vmm_entry = (kvm_vmm_entry *)(KVM_VMM_BASE + | ||
1696 | fdesc_offset); | ||
1697 | func_offset = *(unsigned long *)vmm_info->vmm_entry - module_base; | ||
1698 | p_fdesc = (struct fdesc *)(kvm_vmm_base + fdesc_offset); | ||
1699 | p_fdesc->ip = KVM_VMM_BASE + func_offset; | ||
1700 | p_fdesc->gp = KVM_VMM_BASE+(p_fdesc->gp - module_base); | ||
1701 | |||
1702 | printk(KERN_DEBUG"kvm: Relocated VMM's Init Entry Addr:%lx\n", | ||
1703 | KVM_VMM_BASE+func_offset); | ||
1704 | |||
1705 | fdesc_offset = (unsigned long)vmm_info->tramp_entry - module_base; | ||
1706 | kvm_vmm_info->tramp_entry = (kvm_tramp_entry *)(KVM_VMM_BASE + | ||
1707 | fdesc_offset); | ||
1708 | func_offset = *(unsigned long *)vmm_info->tramp_entry - module_base; | ||
1709 | p_fdesc = (struct fdesc *)(kvm_vmm_base + fdesc_offset); | ||
1710 | p_fdesc->ip = KVM_VMM_BASE + func_offset; | ||
1711 | p_fdesc->gp = KVM_VMM_BASE + (p_fdesc->gp - module_base); | ||
1712 | |||
1713 | kvm_vmm_gp = p_fdesc->gp; | ||
1714 | |||
1715 | printk(KERN_DEBUG"kvm: Relocated VMM's Entry IP:%p\n", | ||
1716 | kvm_vmm_info->vmm_entry); | ||
1717 | printk(KERN_DEBUG"kvm: Relocated VMM's Trampoline Entry IP:0x%lx\n", | ||
1718 | KVM_VMM_BASE + func_offset); | ||
1719 | |||
1720 | return 0; | ||
1721 | } | ||
1722 | |||
1723 | int kvm_arch_init(void *opaque) | ||
1724 | { | ||
1725 | int r; | ||
1726 | struct kvm_vmm_info *vmm_info = (struct kvm_vmm_info *)opaque; | ||
1727 | |||
1728 | if (!vti_cpu_has_kvm_support()) { | ||
1729 | printk(KERN_ERR "kvm: No Hardware Virtualization Support!\n"); | ||
1730 | r = -EOPNOTSUPP; | ||
1731 | goto out; | ||
1732 | } | ||
1733 | |||
1734 | if (kvm_vmm_info) { | ||
1735 | printk(KERN_ERR "kvm: Already loaded VMM module!\n"); | ||
1736 | r = -EEXIST; | ||
1737 | goto out; | ||
1738 | } | ||
1739 | |||
1740 | r = -ENOMEM; | ||
1741 | kvm_vmm_info = kzalloc(sizeof(struct kvm_vmm_info), GFP_KERNEL); | ||
1742 | if (!kvm_vmm_info) | ||
1743 | goto out; | ||
1744 | |||
1745 | if (kvm_alloc_vmm_area()) | ||
1746 | goto out_free0; | ||
1747 | |||
1748 | r = kvm_relocate_vmm(vmm_info, vmm_info->module); | ||
1749 | if (r) | ||
1750 | goto out_free1; | ||
1751 | |||
1752 | return 0; | ||
1753 | |||
1754 | out_free1: | ||
1755 | kvm_free_vmm_area(); | ||
1756 | out_free0: | ||
1757 | kfree(kvm_vmm_info); | ||
1758 | out: | ||
1759 | return r; | ||
1760 | } | ||
1761 | |||
1762 | void kvm_arch_exit(void) | ||
1763 | { | ||
1764 | kvm_free_vmm_area(); | ||
1765 | kfree(kvm_vmm_info); | ||
1766 | kvm_vmm_info = NULL; | ||
1767 | } | ||
1768 | |||
1769 | static void kvm_ia64_sync_dirty_log(struct kvm *kvm, | ||
1770 | struct kvm_memory_slot *memslot) | ||
1771 | { | ||
1772 | int i; | ||
1773 | long base; | ||
1774 | unsigned long n; | ||
1775 | unsigned long *dirty_bitmap = (unsigned long *)(kvm->arch.vm_base + | ||
1776 | offsetof(struct kvm_vm_data, kvm_mem_dirty_log)); | ||
1777 | |||
1778 | n = kvm_dirty_bitmap_bytes(memslot); | ||
1779 | base = memslot->base_gfn / BITS_PER_LONG; | ||
1780 | |||
1781 | spin_lock(&kvm->arch.dirty_log_lock); | ||
1782 | for (i = 0; i < n/sizeof(long); ++i) { | ||
1783 | memslot->dirty_bitmap[i] = dirty_bitmap[base + i]; | ||
1784 | dirty_bitmap[base + i] = 0; | ||
1785 | } | ||
1786 | spin_unlock(&kvm->arch.dirty_log_lock); | ||
1787 | } | ||
1788 | |||
1789 | int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, | ||
1790 | struct kvm_dirty_log *log) | ||
1791 | { | ||
1792 | int r; | ||
1793 | unsigned long n; | ||
1794 | struct kvm_memory_slot *memslot; | ||
1795 | int is_dirty = 0; | ||
1796 | |||
1797 | mutex_lock(&kvm->slots_lock); | ||
1798 | |||
1799 | r = -EINVAL; | ||
1800 | if (log->slot >= KVM_USER_MEM_SLOTS) | ||
1801 | goto out; | ||
1802 | |||
1803 | memslot = id_to_memslot(kvm->memslots, log->slot); | ||
1804 | r = -ENOENT; | ||
1805 | if (!memslot->dirty_bitmap) | ||
1806 | goto out; | ||
1807 | |||
1808 | kvm_ia64_sync_dirty_log(kvm, memslot); | ||
1809 | r = kvm_get_dirty_log(kvm, log, &is_dirty); | ||
1810 | if (r) | ||
1811 | goto out; | ||
1812 | |||
1813 | /* If nothing is dirty, don't bother messing with page tables. */ | ||
1814 | if (is_dirty) { | ||
1815 | kvm_flush_remote_tlbs(kvm); | ||
1816 | n = kvm_dirty_bitmap_bytes(memslot); | ||
1817 | memset(memslot->dirty_bitmap, 0, n); | ||
1818 | } | ||
1819 | r = 0; | ||
1820 | out: | ||
1821 | mutex_unlock(&kvm->slots_lock); | ||
1822 | return r; | ||
1823 | } | ||
1824 | |||
1825 | int kvm_arch_hardware_setup(void) | ||
1826 | { | ||
1827 | return 0; | ||
1828 | } | ||
1829 | |||
1830 | int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq) | ||
1831 | { | ||
1832 | return __apic_accept_irq(vcpu, irq->vector); | ||
1833 | } | ||
1834 | |||
1835 | int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest) | ||
1836 | { | ||
1837 | return apic->vcpu->vcpu_id == dest; | ||
1838 | } | ||
1839 | |||
1840 | int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda) | ||
1841 | { | ||
1842 | return 0; | ||
1843 | } | ||
1844 | |||
1845 | int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2) | ||
1846 | { | ||
1847 | return vcpu1->arch.xtp - vcpu2->arch.xtp; | ||
1848 | } | ||
1849 | |||
1850 | int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, | ||
1851 | int short_hand, int dest, int dest_mode) | ||
1852 | { | ||
1853 | struct kvm_lapic *target = vcpu->arch.apic; | ||
1854 | return (dest_mode == 0) ? | ||
1855 | kvm_apic_match_physical_addr(target, dest) : | ||
1856 | kvm_apic_match_logical_addr(target, dest); | ||
1857 | } | ||
1858 | |||
1859 | static int find_highest_bits(int *dat) | ||
1860 | { | ||
1861 | u32 bits, bitnum; | ||
1862 | int i; | ||
1863 | |||
1864 | /* loop for all 256 bits */ | ||
1865 | for (i = 7; i >= 0 ; i--) { | ||
1866 | bits = dat[i]; | ||
1867 | if (bits) { | ||
1868 | bitnum = fls(bits); | ||
1869 | return i * 32 + bitnum - 1; | ||
1870 | } | ||
1871 | } | ||
1872 | |||
1873 | return -1; | ||
1874 | } | ||
1875 | |||
1876 | int kvm_highest_pending_irq(struct kvm_vcpu *vcpu) | ||
1877 | { | ||
1878 | struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd); | ||
1879 | |||
1880 | if (vpd->irr[0] & (1UL << NMI_VECTOR)) | ||
1881 | return NMI_VECTOR; | ||
1882 | if (vpd->irr[0] & (1UL << ExtINT_VECTOR)) | ||
1883 | return ExtINT_VECTOR; | ||
1884 | |||
1885 | return find_highest_bits((int *)&vpd->irr[0]); | ||
1886 | } | ||
1887 | |||
1888 | int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) | ||
1889 | { | ||
1890 | return vcpu->arch.timer_fired; | ||
1891 | } | ||
1892 | |||
1893 | int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) | ||
1894 | { | ||
1895 | return (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE) || | ||
1896 | (kvm_highest_pending_irq(vcpu) != -1); | ||
1897 | } | ||
1898 | |||
1899 | int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu) | ||
1900 | { | ||
1901 | return (!test_and_set_bit(KVM_REQ_KICK, &vcpu->requests)); | ||
1902 | } | ||
1903 | |||
1904 | int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, | ||
1905 | struct kvm_mp_state *mp_state) | ||
1906 | { | ||
1907 | mp_state->mp_state = vcpu->arch.mp_state; | ||
1908 | return 0; | ||
1909 | } | ||
1910 | |||
1911 | static int vcpu_reset(struct kvm_vcpu *vcpu) | ||
1912 | { | ||
1913 | int r; | ||
1914 | long psr; | ||
1915 | local_irq_save(psr); | ||
1916 | r = kvm_insert_vmm_mapping(vcpu); | ||
1917 | local_irq_restore(psr); | ||
1918 | if (r) | ||
1919 | goto fail; | ||
1920 | |||
1921 | vcpu->arch.launched = 0; | ||
1922 | kvm_arch_vcpu_uninit(vcpu); | ||
1923 | r = kvm_arch_vcpu_init(vcpu); | ||
1924 | if (r) | ||
1925 | goto fail; | ||
1926 | |||
1927 | kvm_purge_vmm_mapping(vcpu); | ||
1928 | r = 0; | ||
1929 | fail: | ||
1930 | return r; | ||
1931 | } | ||
1932 | |||
1933 | int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, | ||
1934 | struct kvm_mp_state *mp_state) | ||
1935 | { | ||
1936 | int r = 0; | ||
1937 | |||
1938 | vcpu->arch.mp_state = mp_state->mp_state; | ||
1939 | if (vcpu->arch.mp_state == KVM_MP_STATE_UNINITIALIZED) | ||
1940 | r = vcpu_reset(vcpu); | ||
1941 | return r; | ||
1942 | } | ||
diff --git a/arch/ia64/kvm/kvm_fw.c b/arch/ia64/kvm/kvm_fw.c deleted file mode 100644 index cb548ee9fcae..000000000000 --- a/arch/ia64/kvm/kvm_fw.c +++ /dev/null | |||
@@ -1,674 +0,0 @@ | |||
1 | /* | ||
2 | * PAL/SAL call delegation | ||
3 | * | ||
4 | * Copyright (c) 2004 Li Susie <susie.li@intel.com> | ||
5 | * Copyright (c) 2005 Yu Ke <ke.yu@intel.com> | ||
6 | * Copyright (c) 2007 Xiantao Zhang <xiantao.zhang@intel.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms and conditions of the GNU General Public License, | ||
10 | * version 2, as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along with | ||
18 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | ||
19 | * Place - Suite 330, Boston, MA 02111-1307 USA. | ||
20 | */ | ||
21 | |||
22 | #include <linux/kvm_host.h> | ||
23 | #include <linux/smp.h> | ||
24 | #include <asm/sn/addrs.h> | ||
25 | #include <asm/sn/clksupport.h> | ||
26 | #include <asm/sn/shub_mmr.h> | ||
27 | |||
28 | #include "vti.h" | ||
29 | #include "misc.h" | ||
30 | |||
31 | #include <asm/pal.h> | ||
32 | #include <asm/sal.h> | ||
33 | #include <asm/tlb.h> | ||
34 | |||
35 | /* | ||
36 | * Handy macros to make sure that the PAL return values start out | ||
37 | * as something meaningful. | ||
38 | */ | ||
39 | #define INIT_PAL_STATUS_UNIMPLEMENTED(x) \ | ||
40 | { \ | ||
41 | x.status = PAL_STATUS_UNIMPLEMENTED; \ | ||
42 | x.v0 = 0; \ | ||
43 | x.v1 = 0; \ | ||
44 | x.v2 = 0; \ | ||
45 | } | ||
46 | |||
47 | #define INIT_PAL_STATUS_SUCCESS(x) \ | ||
48 | { \ | ||
49 | x.status = PAL_STATUS_SUCCESS; \ | ||
50 | x.v0 = 0; \ | ||
51 | x.v1 = 0; \ | ||
52 | x.v2 = 0; \ | ||
53 | } | ||
54 | |||
55 | static void kvm_get_pal_call_data(struct kvm_vcpu *vcpu, | ||
56 | u64 *gr28, u64 *gr29, u64 *gr30, u64 *gr31) { | ||
57 | struct exit_ctl_data *p; | ||
58 | |||
59 | if (vcpu) { | ||
60 | p = &vcpu->arch.exit_data; | ||
61 | if (p->exit_reason == EXIT_REASON_PAL_CALL) { | ||
62 | *gr28 = p->u.pal_data.gr28; | ||
63 | *gr29 = p->u.pal_data.gr29; | ||
64 | *gr30 = p->u.pal_data.gr30; | ||
65 | *gr31 = p->u.pal_data.gr31; | ||
66 | return ; | ||
67 | } | ||
68 | } | ||
69 | printk(KERN_DEBUG"Failed to get vcpu pal data!!!\n"); | ||
70 | } | ||
71 | |||
72 | static void set_pal_result(struct kvm_vcpu *vcpu, | ||
73 | struct ia64_pal_retval result) { | ||
74 | |||
75 | struct exit_ctl_data *p; | ||
76 | |||
77 | p = kvm_get_exit_data(vcpu); | ||
78 | if (p->exit_reason == EXIT_REASON_PAL_CALL) { | ||
79 | p->u.pal_data.ret = result; | ||
80 | return ; | ||
81 | } | ||
82 | INIT_PAL_STATUS_UNIMPLEMENTED(p->u.pal_data.ret); | ||
83 | } | ||
84 | |||
85 | static void set_sal_result(struct kvm_vcpu *vcpu, | ||
86 | struct sal_ret_values result) { | ||
87 | struct exit_ctl_data *p; | ||
88 | |||
89 | p = kvm_get_exit_data(vcpu); | ||
90 | if (p->exit_reason == EXIT_REASON_SAL_CALL) { | ||
91 | p->u.sal_data.ret = result; | ||
92 | return ; | ||
93 | } | ||
94 | printk(KERN_WARNING"Failed to set sal result!!\n"); | ||
95 | } | ||
96 | |||
97 | struct cache_flush_args { | ||
98 | u64 cache_type; | ||
99 | u64 operation; | ||
100 | u64 progress; | ||
101 | long status; | ||
102 | }; | ||
103 | |||
104 | cpumask_t cpu_cache_coherent_map; | ||
105 | |||
106 | static void remote_pal_cache_flush(void *data) | ||
107 | { | ||
108 | struct cache_flush_args *args = data; | ||
109 | long status; | ||
110 | u64 progress = args->progress; | ||
111 | |||
112 | status = ia64_pal_cache_flush(args->cache_type, args->operation, | ||
113 | &progress, NULL); | ||
114 | if (status != 0) | ||
115 | args->status = status; | ||
116 | } | ||
117 | |||
118 | static struct ia64_pal_retval pal_cache_flush(struct kvm_vcpu *vcpu) | ||
119 | { | ||
120 | u64 gr28, gr29, gr30, gr31; | ||
121 | struct ia64_pal_retval result = {0, 0, 0, 0}; | ||
122 | struct cache_flush_args args = {0, 0, 0, 0}; | ||
123 | long psr; | ||
124 | |||
125 | gr28 = gr29 = gr30 = gr31 = 0; | ||
126 | kvm_get_pal_call_data(vcpu, &gr28, &gr29, &gr30, &gr31); | ||
127 | |||
128 | if (gr31 != 0) | ||
129 | printk(KERN_ERR"vcpu:%p called cache_flush error!\n", vcpu); | ||
130 | |||
131 | /* Always call Host Pal in int=1 */ | ||
132 | gr30 &= ~PAL_CACHE_FLUSH_CHK_INTRS; | ||
133 | args.cache_type = gr29; | ||
134 | args.operation = gr30; | ||
135 | smp_call_function(remote_pal_cache_flush, | ||
136 | (void *)&args, 1); | ||
137 | if (args.status != 0) | ||
138 | printk(KERN_ERR"pal_cache_flush error!," | ||
139 | "status:0x%lx\n", args.status); | ||
140 | /* | ||
141 | * Call Host PAL cache flush | ||
142 | * Clear psr.ic when call PAL_CACHE_FLUSH | ||
143 | */ | ||
144 | local_irq_save(psr); | ||
145 | result.status = ia64_pal_cache_flush(gr29, gr30, &result.v1, | ||
146 | &result.v0); | ||
147 | local_irq_restore(psr); | ||
148 | if (result.status != 0) | ||
149 | printk(KERN_ERR"vcpu:%p crashed due to cache_flush err:%ld" | ||
150 | "in1:%lx,in2:%lx\n", | ||
151 | vcpu, result.status, gr29, gr30); | ||
152 | |||
153 | #if 0 | ||
154 | if (gr29 == PAL_CACHE_TYPE_COHERENT) { | ||
155 | cpus_setall(vcpu->arch.cache_coherent_map); | ||
156 | cpu_clear(vcpu->cpu, vcpu->arch.cache_coherent_map); | ||
157 | cpus_setall(cpu_cache_coherent_map); | ||
158 | cpu_clear(vcpu->cpu, cpu_cache_coherent_map); | ||
159 | } | ||
160 | #endif | ||
161 | return result; | ||
162 | } | ||
163 | |||
164 | struct ia64_pal_retval pal_cache_summary(struct kvm_vcpu *vcpu) | ||
165 | { | ||
166 | |||
167 | struct ia64_pal_retval result; | ||
168 | |||
169 | PAL_CALL(result, PAL_CACHE_SUMMARY, 0, 0, 0); | ||
170 | return result; | ||
171 | } | ||
172 | |||
173 | static struct ia64_pal_retval pal_freq_base(struct kvm_vcpu *vcpu) | ||
174 | { | ||
175 | |||
176 | struct ia64_pal_retval result; | ||
177 | |||
178 | PAL_CALL(result, PAL_FREQ_BASE, 0, 0, 0); | ||
179 | |||
180 | /* | ||
181 | * PAL_FREQ_BASE may not be implemented in some platforms, | ||
182 | * call SAL instead. | ||
183 | */ | ||
184 | if (result.v0 == 0) { | ||
185 | result.status = ia64_sal_freq_base(SAL_FREQ_BASE_PLATFORM, | ||
186 | &result.v0, | ||
187 | &result.v1); | ||
188 | result.v2 = 0; | ||
189 | } | ||
190 | |||
191 | return result; | ||
192 | } | ||
193 | |||
194 | /* | ||
195 | * On the SGI SN2, the ITC isn't stable. Emulation backed by the SN2 | ||
196 | * RTC is used instead. This function patches the ratios from SAL | ||
197 | * to match the RTC before providing them to the guest. | ||
198 | */ | ||
199 | static void sn2_patch_itc_freq_ratios(struct ia64_pal_retval *result) | ||
200 | { | ||
201 | struct pal_freq_ratio *ratio; | ||
202 | unsigned long sal_freq, sal_drift, factor; | ||
203 | |||
204 | result->status = ia64_sal_freq_base(SAL_FREQ_BASE_PLATFORM, | ||
205 | &sal_freq, &sal_drift); | ||
206 | ratio = (struct pal_freq_ratio *)&result->v2; | ||
207 | factor = ((sal_freq * 3) + (sn_rtc_cycles_per_second / 2)) / | ||
208 | sn_rtc_cycles_per_second; | ||
209 | |||
210 | ratio->num = 3; | ||
211 | ratio->den = factor; | ||
212 | } | ||
213 | |||
214 | static struct ia64_pal_retval pal_freq_ratios(struct kvm_vcpu *vcpu) | ||
215 | { | ||
216 | struct ia64_pal_retval result; | ||
217 | |||
218 | PAL_CALL(result, PAL_FREQ_RATIOS, 0, 0, 0); | ||
219 | |||
220 | if (vcpu->kvm->arch.is_sn2) | ||
221 | sn2_patch_itc_freq_ratios(&result); | ||
222 | |||
223 | return result; | ||
224 | } | ||
225 | |||
226 | static struct ia64_pal_retval pal_logical_to_physica(struct kvm_vcpu *vcpu) | ||
227 | { | ||
228 | struct ia64_pal_retval result; | ||
229 | |||
230 | INIT_PAL_STATUS_UNIMPLEMENTED(result); | ||
231 | return result; | ||
232 | } | ||
233 | |||
234 | static struct ia64_pal_retval pal_platform_addr(struct kvm_vcpu *vcpu) | ||
235 | { | ||
236 | |||
237 | struct ia64_pal_retval result; | ||
238 | |||
239 | INIT_PAL_STATUS_SUCCESS(result); | ||
240 | return result; | ||
241 | } | ||
242 | |||
243 | static struct ia64_pal_retval pal_proc_get_features(struct kvm_vcpu *vcpu) | ||
244 | { | ||
245 | |||
246 | struct ia64_pal_retval result = {0, 0, 0, 0}; | ||
247 | long in0, in1, in2, in3; | ||
248 | |||
249 | kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3); | ||
250 | result.status = ia64_pal_proc_get_features(&result.v0, &result.v1, | ||
251 | &result.v2, in2); | ||
252 | |||
253 | return result; | ||
254 | } | ||
255 | |||
256 | static struct ia64_pal_retval pal_register_info(struct kvm_vcpu *vcpu) | ||
257 | { | ||
258 | |||
259 | struct ia64_pal_retval result = {0, 0, 0, 0}; | ||
260 | long in0, in1, in2, in3; | ||
261 | |||
262 | kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3); | ||
263 | result.status = ia64_pal_register_info(in1, &result.v1, &result.v2); | ||
264 | |||
265 | return result; | ||
266 | } | ||
267 | |||
268 | static struct ia64_pal_retval pal_cache_info(struct kvm_vcpu *vcpu) | ||
269 | { | ||
270 | |||
271 | pal_cache_config_info_t ci; | ||
272 | long status; | ||
273 | unsigned long in0, in1, in2, in3, r9, r10; | ||
274 | |||
275 | kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3); | ||
276 | status = ia64_pal_cache_config_info(in1, in2, &ci); | ||
277 | r9 = ci.pcci_info_1.pcci1_data; | ||
278 | r10 = ci.pcci_info_2.pcci2_data; | ||
279 | return ((struct ia64_pal_retval){status, r9, r10, 0}); | ||
280 | } | ||
281 | |||
282 | #define GUEST_IMPL_VA_MSB 59 | ||
283 | #define GUEST_RID_BITS 18 | ||
284 | |||
285 | static struct ia64_pal_retval pal_vm_summary(struct kvm_vcpu *vcpu) | ||
286 | { | ||
287 | |||
288 | pal_vm_info_1_u_t vminfo1; | ||
289 | pal_vm_info_2_u_t vminfo2; | ||
290 | struct ia64_pal_retval result; | ||
291 | |||
292 | PAL_CALL(result, PAL_VM_SUMMARY, 0, 0, 0); | ||
293 | if (!result.status) { | ||
294 | vminfo1.pvi1_val = result.v0; | ||
295 | vminfo1.pal_vm_info_1_s.max_itr_entry = 8; | ||
296 | vminfo1.pal_vm_info_1_s.max_dtr_entry = 8; | ||
297 | result.v0 = vminfo1.pvi1_val; | ||
298 | vminfo2.pal_vm_info_2_s.impl_va_msb = GUEST_IMPL_VA_MSB; | ||
299 | vminfo2.pal_vm_info_2_s.rid_size = GUEST_RID_BITS; | ||
300 | result.v1 = vminfo2.pvi2_val; | ||
301 | } | ||
302 | |||
303 | return result; | ||
304 | } | ||
305 | |||
306 | static struct ia64_pal_retval pal_vm_info(struct kvm_vcpu *vcpu) | ||
307 | { | ||
308 | struct ia64_pal_retval result; | ||
309 | unsigned long in0, in1, in2, in3; | ||
310 | |||
311 | kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3); | ||
312 | |||
313 | result.status = ia64_pal_vm_info(in1, in2, | ||
314 | (pal_tc_info_u_t *)&result.v1, &result.v2); | ||
315 | |||
316 | return result; | ||
317 | } | ||
318 | |||
319 | static u64 kvm_get_pal_call_index(struct kvm_vcpu *vcpu) | ||
320 | { | ||
321 | u64 index = 0; | ||
322 | struct exit_ctl_data *p; | ||
323 | |||
324 | p = kvm_get_exit_data(vcpu); | ||
325 | if (p->exit_reason == EXIT_REASON_PAL_CALL) | ||
326 | index = p->u.pal_data.gr28; | ||
327 | |||
328 | return index; | ||
329 | } | ||
330 | |||
331 | static void prepare_for_halt(struct kvm_vcpu *vcpu) | ||
332 | { | ||
333 | vcpu->arch.timer_pending = 1; | ||
334 | vcpu->arch.timer_fired = 0; | ||
335 | } | ||
336 | |||
337 | static struct ia64_pal_retval pal_perf_mon_info(struct kvm_vcpu *vcpu) | ||
338 | { | ||
339 | long status; | ||
340 | unsigned long in0, in1, in2, in3, r9; | ||
341 | unsigned long pm_buffer[16]; | ||
342 | |||
343 | kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3); | ||
344 | status = ia64_pal_perf_mon_info(pm_buffer, | ||
345 | (pal_perf_mon_info_u_t *) &r9); | ||
346 | if (status != 0) { | ||
347 | printk(KERN_DEBUG"PAL_PERF_MON_INFO fails ret=%ld\n", status); | ||
348 | } else { | ||
349 | if (in1) | ||
350 | memcpy((void *)in1, pm_buffer, sizeof(pm_buffer)); | ||
351 | else { | ||
352 | status = PAL_STATUS_EINVAL; | ||
353 | printk(KERN_WARNING"Invalid parameters " | ||
354 | "for PAL call:0x%lx!\n", in0); | ||
355 | } | ||
356 | } | ||
357 | return (struct ia64_pal_retval){status, r9, 0, 0}; | ||
358 | } | ||
359 | |||
360 | static struct ia64_pal_retval pal_halt_info(struct kvm_vcpu *vcpu) | ||
361 | { | ||
362 | unsigned long in0, in1, in2, in3; | ||
363 | long status; | ||
364 | unsigned long res = 1000UL | (1000UL << 16) | (10UL << 32) | ||
365 | | (1UL << 61) | (1UL << 60); | ||
366 | |||
367 | kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3); | ||
368 | if (in1) { | ||
369 | memcpy((void *)in1, &res, sizeof(res)); | ||
370 | status = 0; | ||
371 | } else{ | ||
372 | status = PAL_STATUS_EINVAL; | ||
373 | printk(KERN_WARNING"Invalid parameters " | ||
374 | "for PAL call:0x%lx!\n", in0); | ||
375 | } | ||
376 | |||
377 | return (struct ia64_pal_retval){status, 0, 0, 0}; | ||
378 | } | ||
379 | |||
380 | static struct ia64_pal_retval pal_mem_attrib(struct kvm_vcpu *vcpu) | ||
381 | { | ||
382 | unsigned long r9; | ||
383 | long status; | ||
384 | |||
385 | status = ia64_pal_mem_attrib(&r9); | ||
386 | |||
387 | return (struct ia64_pal_retval){status, r9, 0, 0}; | ||
388 | } | ||
389 | |||
390 | static void remote_pal_prefetch_visibility(void *v) | ||
391 | { | ||
392 | s64 trans_type = (s64)v; | ||
393 | ia64_pal_prefetch_visibility(trans_type); | ||
394 | } | ||
395 | |||
396 | static struct ia64_pal_retval pal_prefetch_visibility(struct kvm_vcpu *vcpu) | ||
397 | { | ||
398 | struct ia64_pal_retval result = {0, 0, 0, 0}; | ||
399 | unsigned long in0, in1, in2, in3; | ||
400 | kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3); | ||
401 | result.status = ia64_pal_prefetch_visibility(in1); | ||
402 | if (result.status == 0) { | ||
403 | /* Must be performed on all remote processors | ||
404 | in the coherence domain. */ | ||
405 | smp_call_function(remote_pal_prefetch_visibility, | ||
406 | (void *)in1, 1); | ||
407 | /* Unnecessary on remote processor for other vcpus!*/ | ||
408 | result.status = 1; | ||
409 | } | ||
410 | return result; | ||
411 | } | ||
412 | |||
413 | static void remote_pal_mc_drain(void *v) | ||
414 | { | ||
415 | ia64_pal_mc_drain(); | ||
416 | } | ||
417 | |||
418 | static struct ia64_pal_retval pal_get_brand_info(struct kvm_vcpu *vcpu) | ||
419 | { | ||
420 | struct ia64_pal_retval result = {0, 0, 0, 0}; | ||
421 | unsigned long in0, in1, in2, in3; | ||
422 | |||
423 | kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3); | ||
424 | |||
425 | if (in1 == 0 && in2) { | ||
426 | char brand_info[128]; | ||
427 | result.status = ia64_pal_get_brand_info(brand_info); | ||
428 | if (result.status == PAL_STATUS_SUCCESS) | ||
429 | memcpy((void *)in2, brand_info, 128); | ||
430 | } else { | ||
431 | result.status = PAL_STATUS_REQUIRES_MEMORY; | ||
432 | printk(KERN_WARNING"Invalid parameters for " | ||
433 | "PAL call:0x%lx!\n", in0); | ||
434 | } | ||
435 | |||
436 | return result; | ||
437 | } | ||
438 | |||
439 | int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *run) | ||
440 | { | ||
441 | |||
442 | u64 gr28; | ||
443 | struct ia64_pal_retval result; | ||
444 | int ret = 1; | ||
445 | |||
446 | gr28 = kvm_get_pal_call_index(vcpu); | ||
447 | switch (gr28) { | ||
448 | case PAL_CACHE_FLUSH: | ||
449 | result = pal_cache_flush(vcpu); | ||
450 | break; | ||
451 | case PAL_MEM_ATTRIB: | ||
452 | result = pal_mem_attrib(vcpu); | ||
453 | break; | ||
454 | case PAL_CACHE_SUMMARY: | ||
455 | result = pal_cache_summary(vcpu); | ||
456 | break; | ||
457 | case PAL_PERF_MON_INFO: | ||
458 | result = pal_perf_mon_info(vcpu); | ||
459 | break; | ||
460 | case PAL_HALT_INFO: | ||
461 | result = pal_halt_info(vcpu); | ||
462 | break; | ||
463 | case PAL_HALT_LIGHT: | ||
464 | { | ||
465 | INIT_PAL_STATUS_SUCCESS(result); | ||
466 | prepare_for_halt(vcpu); | ||
467 | if (kvm_highest_pending_irq(vcpu) == -1) | ||
468 | ret = kvm_emulate_halt(vcpu); | ||
469 | } | ||
470 | break; | ||
471 | |||
472 | case PAL_PREFETCH_VISIBILITY: | ||
473 | result = pal_prefetch_visibility(vcpu); | ||
474 | break; | ||
475 | case PAL_MC_DRAIN: | ||
476 | result.status = ia64_pal_mc_drain(); | ||
477 | /* FIXME: All vcpus likely call PAL_MC_DRAIN. | ||
478 | That causes the congestion. */ | ||
479 | smp_call_function(remote_pal_mc_drain, NULL, 1); | ||
480 | break; | ||
481 | |||
482 | case PAL_FREQ_RATIOS: | ||
483 | result = pal_freq_ratios(vcpu); | ||
484 | break; | ||
485 | |||
486 | case PAL_FREQ_BASE: | ||
487 | result = pal_freq_base(vcpu); | ||
488 | break; | ||
489 | |||
490 | case PAL_LOGICAL_TO_PHYSICAL : | ||
491 | result = pal_logical_to_physica(vcpu); | ||
492 | break; | ||
493 | |||
494 | case PAL_VM_SUMMARY : | ||
495 | result = pal_vm_summary(vcpu); | ||
496 | break; | ||
497 | |||
498 | case PAL_VM_INFO : | ||
499 | result = pal_vm_info(vcpu); | ||
500 | break; | ||
501 | case PAL_PLATFORM_ADDR : | ||
502 | result = pal_platform_addr(vcpu); | ||
503 | break; | ||
504 | case PAL_CACHE_INFO: | ||
505 | result = pal_cache_info(vcpu); | ||
506 | break; | ||
507 | case PAL_PTCE_INFO: | ||
508 | INIT_PAL_STATUS_SUCCESS(result); | ||
509 | result.v1 = (1L << 32) | 1L; | ||
510 | break; | ||
511 | case PAL_REGISTER_INFO: | ||
512 | result = pal_register_info(vcpu); | ||
513 | break; | ||
514 | case PAL_VM_PAGE_SIZE: | ||
515 | result.status = ia64_pal_vm_page_size(&result.v0, | ||
516 | &result.v1); | ||
517 | break; | ||
518 | case PAL_RSE_INFO: | ||
519 | result.status = ia64_pal_rse_info(&result.v0, | ||
520 | (pal_hints_u_t *)&result.v1); | ||
521 | break; | ||
522 | case PAL_PROC_GET_FEATURES: | ||
523 | result = pal_proc_get_features(vcpu); | ||
524 | break; | ||
525 | case PAL_DEBUG_INFO: | ||
526 | result.status = ia64_pal_debug_info(&result.v0, | ||
527 | &result.v1); | ||
528 | break; | ||
529 | case PAL_VERSION: | ||
530 | result.status = ia64_pal_version( | ||
531 | (pal_version_u_t *)&result.v0, | ||
532 | (pal_version_u_t *)&result.v1); | ||
533 | break; | ||
534 | case PAL_FIXED_ADDR: | ||
535 | result.status = PAL_STATUS_SUCCESS; | ||
536 | result.v0 = vcpu->vcpu_id; | ||
537 | break; | ||
538 | case PAL_BRAND_INFO: | ||
539 | result = pal_get_brand_info(vcpu); | ||
540 | break; | ||
541 | case PAL_GET_PSTATE: | ||
542 | case PAL_CACHE_SHARED_INFO: | ||
543 | INIT_PAL_STATUS_UNIMPLEMENTED(result); | ||
544 | break; | ||
545 | default: | ||
546 | INIT_PAL_STATUS_UNIMPLEMENTED(result); | ||
547 | printk(KERN_WARNING"kvm: Unsupported pal call," | ||
548 | " index:0x%lx\n", gr28); | ||
549 | } | ||
550 | set_pal_result(vcpu, result); | ||
551 | return ret; | ||
552 | } | ||
553 | |||
554 | static struct sal_ret_values sal_emulator(struct kvm *kvm, | ||
555 | long index, unsigned long in1, | ||
556 | unsigned long in2, unsigned long in3, | ||
557 | unsigned long in4, unsigned long in5, | ||
558 | unsigned long in6, unsigned long in7) | ||
559 | { | ||
560 | unsigned long r9 = 0; | ||
561 | unsigned long r10 = 0; | ||
562 | long r11 = 0; | ||
563 | long status; | ||
564 | |||
565 | status = 0; | ||
566 | switch (index) { | ||
567 | case SAL_FREQ_BASE: | ||
568 | status = ia64_sal_freq_base(in1, &r9, &r10); | ||
569 | break; | ||
570 | case SAL_PCI_CONFIG_READ: | ||
571 | printk(KERN_WARNING"kvm: Not allowed to call here!" | ||
572 | " SAL_PCI_CONFIG_READ\n"); | ||
573 | break; | ||
574 | case SAL_PCI_CONFIG_WRITE: | ||
575 | printk(KERN_WARNING"kvm: Not allowed to call here!" | ||
576 | " SAL_PCI_CONFIG_WRITE\n"); | ||
577 | break; | ||
578 | case SAL_SET_VECTORS: | ||
579 | if (in1 == SAL_VECTOR_OS_BOOT_RENDEZ) { | ||
580 | if (in4 != 0 || in5 != 0 || in6 != 0 || in7 != 0) { | ||
581 | status = -2; | ||
582 | } else { | ||
583 | kvm->arch.rdv_sal_data.boot_ip = in2; | ||
584 | kvm->arch.rdv_sal_data.boot_gp = in3; | ||
585 | } | ||
586 | printk("Rendvous called! iip:%lx\n\n", in2); | ||
587 | } else | ||
588 | printk(KERN_WARNING"kvm: CALLED SAL_SET_VECTORS %lu." | ||
589 | "ignored...\n", in1); | ||
590 | break; | ||
591 | case SAL_GET_STATE_INFO: | ||
592 | /* No more info. */ | ||
593 | status = -5; | ||
594 | r9 = 0; | ||
595 | break; | ||
596 | case SAL_GET_STATE_INFO_SIZE: | ||
597 | /* Return a dummy size. */ | ||
598 | status = 0; | ||
599 | r9 = 128; | ||
600 | break; | ||
601 | case SAL_CLEAR_STATE_INFO: | ||
602 | /* Noop. */ | ||
603 | break; | ||
604 | case SAL_MC_RENDEZ: | ||
605 | printk(KERN_WARNING | ||
606 | "kvm: called SAL_MC_RENDEZ. ignored...\n"); | ||
607 | break; | ||
608 | case SAL_MC_SET_PARAMS: | ||
609 | printk(KERN_WARNING | ||
610 | "kvm: called SAL_MC_SET_PARAMS.ignored!\n"); | ||
611 | break; | ||
612 | case SAL_CACHE_FLUSH: | ||
613 | if (1) { | ||
614 | /*Flush using SAL. | ||
615 | This method is faster but has a side | ||
616 | effect on other vcpu running on | ||
617 | this cpu. */ | ||
618 | status = ia64_sal_cache_flush(in1); | ||
619 | } else { | ||
620 | /*Maybe need to implement the method | ||
621 | without side effect!*/ | ||
622 | status = 0; | ||
623 | } | ||
624 | break; | ||
625 | case SAL_CACHE_INIT: | ||
626 | printk(KERN_WARNING | ||
627 | "kvm: called SAL_CACHE_INIT. ignored...\n"); | ||
628 | break; | ||
629 | case SAL_UPDATE_PAL: | ||
630 | printk(KERN_WARNING | ||
631 | "kvm: CALLED SAL_UPDATE_PAL. ignored...\n"); | ||
632 | break; | ||
633 | default: | ||
634 | printk(KERN_WARNING"kvm: called SAL_CALL with unknown index." | ||
635 | " index:%ld\n", index); | ||
636 | status = -1; | ||
637 | break; | ||
638 | } | ||
639 | return ((struct sal_ret_values) {status, r9, r10, r11}); | ||
640 | } | ||
641 | |||
642 | static void kvm_get_sal_call_data(struct kvm_vcpu *vcpu, u64 *in0, u64 *in1, | ||
643 | u64 *in2, u64 *in3, u64 *in4, u64 *in5, u64 *in6, u64 *in7){ | ||
644 | |||
645 | struct exit_ctl_data *p; | ||
646 | |||
647 | p = kvm_get_exit_data(vcpu); | ||
648 | |||
649 | if (p->exit_reason == EXIT_REASON_SAL_CALL) { | ||
650 | *in0 = p->u.sal_data.in0; | ||
651 | *in1 = p->u.sal_data.in1; | ||
652 | *in2 = p->u.sal_data.in2; | ||
653 | *in3 = p->u.sal_data.in3; | ||
654 | *in4 = p->u.sal_data.in4; | ||
655 | *in5 = p->u.sal_data.in5; | ||
656 | *in6 = p->u.sal_data.in6; | ||
657 | *in7 = p->u.sal_data.in7; | ||
658 | return ; | ||
659 | } | ||
660 | *in0 = 0; | ||
661 | } | ||
662 | |||
663 | void kvm_sal_emul(struct kvm_vcpu *vcpu) | ||
664 | { | ||
665 | |||
666 | struct sal_ret_values result; | ||
667 | u64 index, in1, in2, in3, in4, in5, in6, in7; | ||
668 | |||
669 | kvm_get_sal_call_data(vcpu, &index, &in1, &in2, | ||
670 | &in3, &in4, &in5, &in6, &in7); | ||
671 | result = sal_emulator(vcpu->kvm, index, in1, in2, in3, | ||
672 | in4, in5, in6, in7); | ||
673 | set_sal_result(vcpu, result); | ||
674 | } | ||
diff --git a/arch/ia64/kvm/kvm_lib.c b/arch/ia64/kvm/kvm_lib.c deleted file mode 100644 index f1268b8e6f9e..000000000000 --- a/arch/ia64/kvm/kvm_lib.c +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | /* | ||
2 | * kvm_lib.c: Compile some libraries for kvm-intel module. | ||
3 | * | ||
4 | * Just include kernel's library, and disable symbols export. | ||
5 | * Copyright (C) 2008, Intel Corporation. | ||
6 | * Xiantao Zhang (xiantao.zhang@intel.com) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | #undef CONFIG_MODULES | ||
14 | #include <linux/module.h> | ||
15 | #undef CONFIG_KALLSYMS | ||
16 | #undef EXPORT_SYMBOL | ||
17 | #undef EXPORT_SYMBOL_GPL | ||
18 | #define EXPORT_SYMBOL(sym) | ||
19 | #define EXPORT_SYMBOL_GPL(sym) | ||
20 | #include "../../../lib/vsprintf.c" | ||
21 | #include "../../../lib/ctype.c" | ||
diff --git a/arch/ia64/kvm/kvm_minstate.h b/arch/ia64/kvm/kvm_minstate.h deleted file mode 100644 index b2bcaa2787aa..000000000000 --- a/arch/ia64/kvm/kvm_minstate.h +++ /dev/null | |||
@@ -1,266 +0,0 @@ | |||
1 | /* | ||
2 | * kvm_minstate.h: min save macros | ||
3 | * Copyright (c) 2007, Intel Corporation. | ||
4 | * | ||
5 | * Xuefei Xu (Anthony Xu) (Anthony.xu@intel.com) | ||
6 | * Xiantao Zhang (xiantao.zhang@intel.com) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms and conditions of the GNU General Public License, | ||
10 | * version 2, as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along with | ||
18 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | ||
19 | * Place - Suite 330, Boston, MA 02111-1307 USA. | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | |||
24 | #include <asm/asmmacro.h> | ||
25 | #include <asm/types.h> | ||
26 | #include <asm/kregs.h> | ||
27 | #include <asm/kvm_host.h> | ||
28 | |||
29 | #include "asm-offsets.h" | ||
30 | |||
31 | #define KVM_MINSTATE_START_SAVE_MIN \ | ||
32 | mov ar.rsc = 0;/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */\ | ||
33 | ;; \ | ||
34 | mov.m r28 = ar.rnat; \ | ||
35 | addl r22 = VMM_RBS_OFFSET,r1; /* compute base of RBS */ \ | ||
36 | ;; \ | ||
37 | lfetch.fault.excl.nt1 [r22]; \ | ||
38 | addl r1 = KVM_STK_OFFSET-VMM_PT_REGS_SIZE, r1; \ | ||
39 | mov r23 = ar.bspstore; /* save ar.bspstore */ \ | ||
40 | ;; \ | ||
41 | mov ar.bspstore = r22; /* switch to kernel RBS */\ | ||
42 | ;; \ | ||
43 | mov r18 = ar.bsp; \ | ||
44 | mov ar.rsc = 0x3; /* set eager mode, pl 0, little-endian, loadrs=0 */ | ||
45 | |||
46 | |||
47 | |||
48 | #define KVM_MINSTATE_END_SAVE_MIN \ | ||
49 | bsw.1; /* switch back to bank 1 (must be last in insn group) */\ | ||
50 | ;; | ||
51 | |||
52 | |||
53 | #define PAL_VSA_SYNC_READ \ | ||
54 | /* begin to call pal vps sync_read */ \ | ||
55 | {.mii; \ | ||
56 | add r25 = VMM_VPD_BASE_OFFSET, r21; \ | ||
57 | nop 0x0; \ | ||
58 | mov r24=ip; \ | ||
59 | ;; \ | ||
60 | } \ | ||
61 | {.mmb \ | ||
62 | add r24=0x20, r24; \ | ||
63 | ld8 r25 = [r25]; /* read vpd base */ \ | ||
64 | br.cond.sptk kvm_vps_sync_read; /*call the service*/ \ | ||
65 | ;; \ | ||
66 | }; \ | ||
67 | |||
68 | |||
69 | #define KVM_MINSTATE_GET_CURRENT(reg) mov reg=r21 | ||
70 | |||
71 | /* | ||
72 | * KVM_DO_SAVE_MIN switches to the kernel stacks (if necessary) and saves | ||
73 | * the minimum state necessary that allows us to turn psr.ic back | ||
74 | * on. | ||
75 | * | ||
76 | * Assumed state upon entry: | ||
77 | * psr.ic: off | ||
78 | * r31: contains saved predicates (pr) | ||
79 | * | ||
80 | * Upon exit, the state is as follows: | ||
81 | * psr.ic: off | ||
82 | * r2 = points to &pt_regs.r16 | ||
83 | * r8 = contents of ar.ccv | ||
84 | * r9 = contents of ar.csd | ||
85 | * r10 = contents of ar.ssd | ||
86 | * r11 = FPSR_DEFAULT | ||
87 | * r12 = kernel sp (kernel virtual address) | ||
88 | * r13 = points to current task_struct (kernel virtual address) | ||
89 | * p15 = TRUE if psr.i is set in cr.ipsr | ||
90 | * predicate registers (other than p2, p3, and p15), b6, r3, r14, r15: | ||
91 | * preserved | ||
92 | * | ||
93 | * Note that psr.ic is NOT turned on by this macro. This is so that | ||
94 | * we can pass interruption state as arguments to a handler. | ||
95 | */ | ||
96 | |||
97 | |||
98 | #define PT(f) (VMM_PT_REGS_##f##_OFFSET) | ||
99 | |||
100 | #define KVM_DO_SAVE_MIN(COVER,SAVE_IFS,EXTRA) \ | ||
101 | KVM_MINSTATE_GET_CURRENT(r16); /* M (or M;;I) */ \ | ||
102 | mov r27 = ar.rsc; /* M */ \ | ||
103 | mov r20 = r1; /* A */ \ | ||
104 | mov r25 = ar.unat; /* M */ \ | ||
105 | mov r29 = cr.ipsr; /* M */ \ | ||
106 | mov r26 = ar.pfs; /* I */ \ | ||
107 | mov r18 = cr.isr; \ | ||
108 | COVER; /* B;; (or nothing) */ \ | ||
109 | ;; \ | ||
110 | tbit.z p0,p15 = r29,IA64_PSR_I_BIT; \ | ||
111 | mov r1 = r16; \ | ||
112 | /* mov r21=r16; */ \ | ||
113 | /* switch from user to kernel RBS: */ \ | ||
114 | ;; \ | ||
115 | invala; /* M */ \ | ||
116 | SAVE_IFS; \ | ||
117 | ;; \ | ||
118 | KVM_MINSTATE_START_SAVE_MIN \ | ||
119 | adds r17 = 2*L1_CACHE_BYTES,r1;/* cache-line size */ \ | ||
120 | adds r16 = PT(CR_IPSR),r1; \ | ||
121 | ;; \ | ||
122 | lfetch.fault.excl.nt1 [r17],L1_CACHE_BYTES; \ | ||
123 | st8 [r16] = r29; /* save cr.ipsr */ \ | ||
124 | ;; \ | ||
125 | lfetch.fault.excl.nt1 [r17]; \ | ||
126 | tbit.nz p15,p0 = r29,IA64_PSR_I_BIT; \ | ||
127 | mov r29 = b0 \ | ||
128 | ;; \ | ||
129 | adds r16 = PT(R8),r1; /* initialize first base pointer */\ | ||
130 | adds r17 = PT(R9),r1; /* initialize second base pointer */\ | ||
131 | ;; \ | ||
132 | .mem.offset 0,0; st8.spill [r16] = r8,16; \ | ||
133 | .mem.offset 8,0; st8.spill [r17] = r9,16; \ | ||
134 | ;; \ | ||
135 | .mem.offset 0,0; st8.spill [r16] = r10,24; \ | ||
136 | .mem.offset 8,0; st8.spill [r17] = r11,24; \ | ||
137 | ;; \ | ||
138 | mov r9 = cr.iip; /* M */ \ | ||
139 | mov r10 = ar.fpsr; /* M */ \ | ||
140 | ;; \ | ||
141 | st8 [r16] = r9,16; /* save cr.iip */ \ | ||
142 | st8 [r17] = r30,16; /* save cr.ifs */ \ | ||
143 | sub r18 = r18,r22; /* r18=RSE.ndirty*8 */ \ | ||
144 | ;; \ | ||
145 | st8 [r16] = r25,16; /* save ar.unat */ \ | ||
146 | st8 [r17] = r26,16; /* save ar.pfs */ \ | ||
147 | shl r18 = r18,16; /* calu ar.rsc used for "loadrs" */\ | ||
148 | ;; \ | ||
149 | st8 [r16] = r27,16; /* save ar.rsc */ \ | ||
150 | st8 [r17] = r28,16; /* save ar.rnat */ \ | ||
151 | ;; /* avoid RAW on r16 & r17 */ \ | ||
152 | st8 [r16] = r23,16; /* save ar.bspstore */ \ | ||
153 | st8 [r17] = r31,16; /* save predicates */ \ | ||
154 | ;; \ | ||
155 | st8 [r16] = r29,16; /* save b0 */ \ | ||
156 | st8 [r17] = r18,16; /* save ar.rsc value for "loadrs" */\ | ||
157 | ;; \ | ||
158 | .mem.offset 0,0; st8.spill [r16] = r20,16;/* save original r1 */ \ | ||
159 | .mem.offset 8,0; st8.spill [r17] = r12,16; \ | ||
160 | adds r12 = -16,r1; /* switch to kernel memory stack */ \ | ||
161 | ;; \ | ||
162 | .mem.offset 0,0; st8.spill [r16] = r13,16; \ | ||
163 | .mem.offset 8,0; st8.spill [r17] = r10,16; /* save ar.fpsr */\ | ||
164 | mov r13 = r21; /* establish `current' */ \ | ||
165 | ;; \ | ||
166 | .mem.offset 0,0; st8.spill [r16] = r15,16; \ | ||
167 | .mem.offset 8,0; st8.spill [r17] = r14,16; \ | ||
168 | ;; \ | ||
169 | .mem.offset 0,0; st8.spill [r16] = r2,16; \ | ||
170 | .mem.offset 8,0; st8.spill [r17] = r3,16; \ | ||
171 | adds r2 = VMM_PT_REGS_R16_OFFSET,r1; \ | ||
172 | ;; \ | ||
173 | adds r16 = VMM_VCPU_IIPA_OFFSET,r13; \ | ||
174 | adds r17 = VMM_VCPU_ISR_OFFSET,r13; \ | ||
175 | mov r26 = cr.iipa; \ | ||
176 | mov r27 = cr.isr; \ | ||
177 | ;; \ | ||
178 | st8 [r16] = r26; \ | ||
179 | st8 [r17] = r27; \ | ||
180 | ;; \ | ||
181 | EXTRA; \ | ||
182 | mov r8 = ar.ccv; \ | ||
183 | mov r9 = ar.csd; \ | ||
184 | mov r10 = ar.ssd; \ | ||
185 | movl r11 = FPSR_DEFAULT; /* L-unit */ \ | ||
186 | adds r17 = VMM_VCPU_GP_OFFSET,r13; \ | ||
187 | ;; \ | ||
188 | ld8 r1 = [r17];/* establish kernel global pointer */ \ | ||
189 | ;; \ | ||
190 | PAL_VSA_SYNC_READ \ | ||
191 | KVM_MINSTATE_END_SAVE_MIN | ||
192 | |||
193 | /* | ||
194 | * SAVE_REST saves the remainder of pt_regs (with psr.ic on). | ||
195 | * | ||
196 | * Assumed state upon entry: | ||
197 | * psr.ic: on | ||
198 | * r2: points to &pt_regs.f6 | ||
199 | * r3: points to &pt_regs.f7 | ||
200 | * r8: contents of ar.ccv | ||
201 | * r9: contents of ar.csd | ||
202 | * r10: contents of ar.ssd | ||
203 | * r11: FPSR_DEFAULT | ||
204 | * | ||
205 | * Registers r14 and r15 are guaranteed not to be touched by SAVE_REST. | ||
206 | */ | ||
207 | #define KVM_SAVE_REST \ | ||
208 | .mem.offset 0,0; st8.spill [r2] = r16,16; \ | ||
209 | .mem.offset 8,0; st8.spill [r3] = r17,16; \ | ||
210 | ;; \ | ||
211 | .mem.offset 0,0; st8.spill [r2] = r18,16; \ | ||
212 | .mem.offset 8,0; st8.spill [r3] = r19,16; \ | ||
213 | ;; \ | ||
214 | .mem.offset 0,0; st8.spill [r2] = r20,16; \ | ||
215 | .mem.offset 8,0; st8.spill [r3] = r21,16; \ | ||
216 | mov r18=b6; \ | ||
217 | ;; \ | ||
218 | .mem.offset 0,0; st8.spill [r2] = r22,16; \ | ||
219 | .mem.offset 8,0; st8.spill [r3] = r23,16; \ | ||
220 | mov r19 = b7; \ | ||
221 | ;; \ | ||
222 | .mem.offset 0,0; st8.spill [r2] = r24,16; \ | ||
223 | .mem.offset 8,0; st8.spill [r3] = r25,16; \ | ||
224 | ;; \ | ||
225 | .mem.offset 0,0; st8.spill [r2] = r26,16; \ | ||
226 | .mem.offset 8,0; st8.spill [r3] = r27,16; \ | ||
227 | ;; \ | ||
228 | .mem.offset 0,0; st8.spill [r2] = r28,16; \ | ||
229 | .mem.offset 8,0; st8.spill [r3] = r29,16; \ | ||
230 | ;; \ | ||
231 | .mem.offset 0,0; st8.spill [r2] = r30,16; \ | ||
232 | .mem.offset 8,0; st8.spill [r3] = r31,32; \ | ||
233 | ;; \ | ||
234 | mov ar.fpsr = r11; \ | ||
235 | st8 [r2] = r8,8; \ | ||
236 | adds r24 = PT(B6)-PT(F7),r3; \ | ||
237 | adds r25 = PT(B7)-PT(F7),r3; \ | ||
238 | ;; \ | ||
239 | st8 [r24] = r18,16; /* b6 */ \ | ||
240 | st8 [r25] = r19,16; /* b7 */ \ | ||
241 | adds r2 = PT(R4)-PT(F6),r2; \ | ||
242 | adds r3 = PT(R5)-PT(F7),r3; \ | ||
243 | ;; \ | ||
244 | st8 [r24] = r9; /* ar.csd */ \ | ||
245 | st8 [r25] = r10; /* ar.ssd */ \ | ||
246 | ;; \ | ||
247 | mov r18 = ar.unat; \ | ||
248 | adds r19 = PT(EML_UNAT)-PT(R4),r2; \ | ||
249 | ;; \ | ||
250 | st8 [r19] = r18; /* eml_unat */ \ | ||
251 | |||
252 | |||
253 | #define KVM_SAVE_EXTRA \ | ||
254 | .mem.offset 0,0; st8.spill [r2] = r4,16; \ | ||
255 | .mem.offset 8,0; st8.spill [r3] = r5,16; \ | ||
256 | ;; \ | ||
257 | .mem.offset 0,0; st8.spill [r2] = r6,16; \ | ||
258 | .mem.offset 8,0; st8.spill [r3] = r7; \ | ||
259 | ;; \ | ||
260 | mov r26 = ar.unat; \ | ||
261 | ;; \ | ||
262 | st8 [r2] = r26;/* eml_unat */ \ | ||
263 | |||
264 | #define KVM_SAVE_MIN_WITH_COVER KVM_DO_SAVE_MIN(cover, mov r30 = cr.ifs,) | ||
265 | #define KVM_SAVE_MIN_WITH_COVER_R19 KVM_DO_SAVE_MIN(cover, mov r30 = cr.ifs, mov r15 = r19) | ||
266 | #define KVM_SAVE_MIN KVM_DO_SAVE_MIN( , mov r30 = r0, ) | ||
diff --git a/arch/ia64/kvm/lapic.h b/arch/ia64/kvm/lapic.h deleted file mode 100644 index c5f92a926a9a..000000000000 --- a/arch/ia64/kvm/lapic.h +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | #ifndef __KVM_IA64_LAPIC_H | ||
2 | #define __KVM_IA64_LAPIC_H | ||
3 | |||
4 | #include <linux/kvm_host.h> | ||
5 | |||
6 | /* | ||
7 | * vlsapic | ||
8 | */ | ||
9 | struct kvm_lapic{ | ||
10 | struct kvm_vcpu *vcpu; | ||
11 | uint64_t insvc[4]; | ||
12 | uint64_t vhpi; | ||
13 | uint8_t xtp; | ||
14 | uint8_t pal_init_pending; | ||
15 | uint8_t pad[2]; | ||
16 | }; | ||
17 | |||
18 | int kvm_create_lapic(struct kvm_vcpu *vcpu); | ||
19 | void kvm_free_lapic(struct kvm_vcpu *vcpu); | ||
20 | |||
21 | int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest); | ||
22 | int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda); | ||
23 | int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, | ||
24 | int short_hand, int dest, int dest_mode); | ||
25 | int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2); | ||
26 | int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq); | ||
27 | #define kvm_apic_present(x) (true) | ||
28 | #define kvm_lapic_enabled(x) (true) | ||
29 | |||
30 | #endif | ||
diff --git a/arch/ia64/kvm/memcpy.S b/arch/ia64/kvm/memcpy.S deleted file mode 100644 index c04cdbe9f80f..000000000000 --- a/arch/ia64/kvm/memcpy.S +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | #include "../lib/memcpy.S" | ||
diff --git a/arch/ia64/kvm/memset.S b/arch/ia64/kvm/memset.S deleted file mode 100644 index 83c3066d844a..000000000000 --- a/arch/ia64/kvm/memset.S +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | #include "../lib/memset.S" | ||
diff --git a/arch/ia64/kvm/misc.h b/arch/ia64/kvm/misc.h deleted file mode 100644 index dd979e00b574..000000000000 --- a/arch/ia64/kvm/misc.h +++ /dev/null | |||
@@ -1,94 +0,0 @@ | |||
1 | #ifndef __KVM_IA64_MISC_H | ||
2 | #define __KVM_IA64_MISC_H | ||
3 | |||
4 | #include <linux/kvm_host.h> | ||
5 | /* | ||
6 | * misc.h | ||
7 | * Copyright (C) 2007, Intel Corporation. | ||
8 | * Xiantao Zhang (xiantao.zhang@intel.com) | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms and conditions of the GNU General Public License, | ||
12 | * version 2, as published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
15 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
17 | * more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along with | ||
20 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | ||
21 | * Place - Suite 330, Boston, MA 02111-1307 USA. | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | /* | ||
26 | *Return p2m base address at host side! | ||
27 | */ | ||
28 | static inline uint64_t *kvm_host_get_pmt(struct kvm *kvm) | ||
29 | { | ||
30 | return (uint64_t *)(kvm->arch.vm_base + | ||
31 | offsetof(struct kvm_vm_data, kvm_p2m)); | ||
32 | } | ||
33 | |||
34 | static inline void kvm_set_pmt_entry(struct kvm *kvm, gfn_t gfn, | ||
35 | u64 paddr, u64 mem_flags) | ||
36 | { | ||
37 | uint64_t *pmt_base = kvm_host_get_pmt(kvm); | ||
38 | unsigned long pte; | ||
39 | |||
40 | pte = PAGE_ALIGN(paddr) | mem_flags; | ||
41 | pmt_base[gfn] = pte; | ||
42 | } | ||
43 | |||
44 | /*Function for translating host address to guest address*/ | ||
45 | |||
46 | static inline void *to_guest(struct kvm *kvm, void *addr) | ||
47 | { | ||
48 | return (void *)((unsigned long)(addr) - kvm->arch.vm_base + | ||
49 | KVM_VM_DATA_BASE); | ||
50 | } | ||
51 | |||
52 | /*Function for translating guest address to host address*/ | ||
53 | |||
54 | static inline void *to_host(struct kvm *kvm, void *addr) | ||
55 | { | ||
56 | return (void *)((unsigned long)addr - KVM_VM_DATA_BASE | ||
57 | + kvm->arch.vm_base); | ||
58 | } | ||
59 | |||
60 | /* Get host context of the vcpu */ | ||
61 | static inline union context *kvm_get_host_context(struct kvm_vcpu *vcpu) | ||
62 | { | ||
63 | union context *ctx = &vcpu->arch.host; | ||
64 | return to_guest(vcpu->kvm, ctx); | ||
65 | } | ||
66 | |||
67 | /* Get guest context of the vcpu */ | ||
68 | static inline union context *kvm_get_guest_context(struct kvm_vcpu *vcpu) | ||
69 | { | ||
70 | union context *ctx = &vcpu->arch.guest; | ||
71 | return to_guest(vcpu->kvm, ctx); | ||
72 | } | ||
73 | |||
74 | /* kvm get exit data from gvmm! */ | ||
75 | static inline struct exit_ctl_data *kvm_get_exit_data(struct kvm_vcpu *vcpu) | ||
76 | { | ||
77 | return &vcpu->arch.exit_data; | ||
78 | } | ||
79 | |||
80 | /*kvm get vcpu ioreq for kvm module!*/ | ||
81 | static inline struct kvm_mmio_req *kvm_get_vcpu_ioreq(struct kvm_vcpu *vcpu) | ||
82 | { | ||
83 | struct exit_ctl_data *p_ctl_data; | ||
84 | |||
85 | if (vcpu) { | ||
86 | p_ctl_data = kvm_get_exit_data(vcpu); | ||
87 | if (p_ctl_data->exit_reason == EXIT_REASON_MMIO_INSTRUCTION) | ||
88 | return &p_ctl_data->u.ioreq; | ||
89 | } | ||
90 | |||
91 | return NULL; | ||
92 | } | ||
93 | |||
94 | #endif | ||
diff --git a/arch/ia64/kvm/mmio.c b/arch/ia64/kvm/mmio.c deleted file mode 100644 index f1e17d3d6cd9..000000000000 --- a/arch/ia64/kvm/mmio.c +++ /dev/null | |||
@@ -1,336 +0,0 @@ | |||
1 | /* | ||
2 | * mmio.c: MMIO emulation components. | ||
3 | * Copyright (c) 2004, Intel Corporation. | ||
4 | * Yaozu Dong (Eddie Dong) (Eddie.dong@intel.com) | ||
5 | * Kun Tian (Kevin Tian) (Kevin.tian@intel.com) | ||
6 | * | ||
7 | * Copyright (c) 2007 Intel Corporation KVM support. | ||
8 | * Xuefei Xu (Anthony Xu) (anthony.xu@intel.com) | ||
9 | * Xiantao Zhang (xiantao.zhang@intel.com) | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms and conditions of the GNU General Public License, | ||
13 | * version 2, as published by the Free Software Foundation. | ||
14 | * | ||
15 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
16 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
18 | * more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License along with | ||
21 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | ||
22 | * Place - Suite 330, Boston, MA 02111-1307 USA. | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #include <linux/kvm_host.h> | ||
27 | |||
28 | #include "vcpu.h" | ||
29 | |||
30 | static void vlsapic_write_xtp(struct kvm_vcpu *v, uint8_t val) | ||
31 | { | ||
32 | VLSAPIC_XTP(v) = val; | ||
33 | } | ||
34 | |||
35 | /* | ||
36 | * LSAPIC OFFSET | ||
37 | */ | ||
38 | #define PIB_LOW_HALF(ofst) !(ofst & (1 << 20)) | ||
39 | #define PIB_OFST_INTA 0x1E0000 | ||
40 | #define PIB_OFST_XTP 0x1E0008 | ||
41 | |||
42 | /* | ||
43 | * execute write IPI op. | ||
44 | */ | ||
45 | static void vlsapic_write_ipi(struct kvm_vcpu *vcpu, | ||
46 | uint64_t addr, uint64_t data) | ||
47 | { | ||
48 | struct exit_ctl_data *p = ¤t_vcpu->arch.exit_data; | ||
49 | unsigned long psr; | ||
50 | |||
51 | local_irq_save(psr); | ||
52 | |||
53 | p->exit_reason = EXIT_REASON_IPI; | ||
54 | p->u.ipi_data.addr.val = addr; | ||
55 | p->u.ipi_data.data.val = data; | ||
56 | vmm_transition(current_vcpu); | ||
57 | |||
58 | local_irq_restore(psr); | ||
59 | |||
60 | } | ||
61 | |||
62 | void lsapic_write(struct kvm_vcpu *v, unsigned long addr, | ||
63 | unsigned long length, unsigned long val) | ||
64 | { | ||
65 | addr &= (PIB_SIZE - 1); | ||
66 | |||
67 | switch (addr) { | ||
68 | case PIB_OFST_INTA: | ||
69 | panic_vm(v, "Undefined write on PIB INTA\n"); | ||
70 | break; | ||
71 | case PIB_OFST_XTP: | ||
72 | if (length == 1) { | ||
73 | vlsapic_write_xtp(v, val); | ||
74 | } else { | ||
75 | panic_vm(v, "Undefined write on PIB XTP\n"); | ||
76 | } | ||
77 | break; | ||
78 | default: | ||
79 | if (PIB_LOW_HALF(addr)) { | ||
80 | /*Lower half */ | ||
81 | if (length != 8) | ||
82 | panic_vm(v, "Can't LHF write with size %ld!\n", | ||
83 | length); | ||
84 | else | ||
85 | vlsapic_write_ipi(v, addr, val); | ||
86 | } else { /*Upper half */ | ||
87 | panic_vm(v, "IPI-UHF write %lx\n", addr); | ||
88 | } | ||
89 | break; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | unsigned long lsapic_read(struct kvm_vcpu *v, unsigned long addr, | ||
94 | unsigned long length) | ||
95 | { | ||
96 | uint64_t result = 0; | ||
97 | |||
98 | addr &= (PIB_SIZE - 1); | ||
99 | |||
100 | switch (addr) { | ||
101 | case PIB_OFST_INTA: | ||
102 | if (length == 1) /* 1 byte load */ | ||
103 | ; /* There is no i8259, there is no INTA access*/ | ||
104 | else | ||
105 | panic_vm(v, "Undefined read on PIB INTA\n"); | ||
106 | |||
107 | break; | ||
108 | case PIB_OFST_XTP: | ||
109 | if (length == 1) { | ||
110 | result = VLSAPIC_XTP(v); | ||
111 | } else { | ||
112 | panic_vm(v, "Undefined read on PIB XTP\n"); | ||
113 | } | ||
114 | break; | ||
115 | default: | ||
116 | panic_vm(v, "Undefined addr access for lsapic!\n"); | ||
117 | break; | ||
118 | } | ||
119 | return result; | ||
120 | } | ||
121 | |||
122 | static void mmio_access(struct kvm_vcpu *vcpu, u64 src_pa, u64 *dest, | ||
123 | u16 s, int ma, int dir) | ||
124 | { | ||
125 | unsigned long iot; | ||
126 | struct exit_ctl_data *p = &vcpu->arch.exit_data; | ||
127 | unsigned long psr; | ||
128 | |||
129 | iot = __gpfn_is_io(src_pa >> PAGE_SHIFT); | ||
130 | |||
131 | local_irq_save(psr); | ||
132 | |||
133 | /*Intercept the access for PIB range*/ | ||
134 | if (iot == GPFN_PIB) { | ||
135 | if (!dir) | ||
136 | lsapic_write(vcpu, src_pa, s, *dest); | ||
137 | else | ||
138 | *dest = lsapic_read(vcpu, src_pa, s); | ||
139 | goto out; | ||
140 | } | ||
141 | p->exit_reason = EXIT_REASON_MMIO_INSTRUCTION; | ||
142 | p->u.ioreq.addr = src_pa; | ||
143 | p->u.ioreq.size = s; | ||
144 | p->u.ioreq.dir = dir; | ||
145 | if (dir == IOREQ_WRITE) | ||
146 | p->u.ioreq.data = *dest; | ||
147 | p->u.ioreq.state = STATE_IOREQ_READY; | ||
148 | vmm_transition(vcpu); | ||
149 | |||
150 | if (p->u.ioreq.state == STATE_IORESP_READY) { | ||
151 | if (dir == IOREQ_READ) | ||
152 | /* it's necessary to ensure zero extending */ | ||
153 | *dest = p->u.ioreq.data & (~0UL >> (64-(s*8))); | ||
154 | } else | ||
155 | panic_vm(vcpu, "Unhandled mmio access returned!\n"); | ||
156 | out: | ||
157 | local_irq_restore(psr); | ||
158 | return ; | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | dir 1: read 0:write | ||
163 | inst_type 0:integer 1:floating point | ||
164 | */ | ||
165 | #define SL_INTEGER 0 /* store/load interger*/ | ||
166 | #define SL_FLOATING 1 /* store/load floating*/ | ||
167 | |||
168 | void emulate_io_inst(struct kvm_vcpu *vcpu, u64 padr, u64 ma) | ||
169 | { | ||
170 | struct kvm_pt_regs *regs; | ||
171 | IA64_BUNDLE bundle; | ||
172 | int slot, dir = 0; | ||
173 | int inst_type = -1; | ||
174 | u16 size = 0; | ||
175 | u64 data, slot1a, slot1b, temp, update_reg; | ||
176 | s32 imm; | ||
177 | INST64 inst; | ||
178 | |||
179 | regs = vcpu_regs(vcpu); | ||
180 | |||
181 | if (fetch_code(vcpu, regs->cr_iip, &bundle)) { | ||
182 | /* if fetch code fail, return and try again */ | ||
183 | return; | ||
184 | } | ||
185 | slot = ((struct ia64_psr *)&(regs->cr_ipsr))->ri; | ||
186 | if (!slot) | ||
187 | inst.inst = bundle.slot0; | ||
188 | else if (slot == 1) { | ||
189 | slot1a = bundle.slot1a; | ||
190 | slot1b = bundle.slot1b; | ||
191 | inst.inst = slot1a + (slot1b << 18); | ||
192 | } else if (slot == 2) | ||
193 | inst.inst = bundle.slot2; | ||
194 | |||
195 | /* Integer Load/Store */ | ||
196 | if (inst.M1.major == 4 && inst.M1.m == 0 && inst.M1.x == 0) { | ||
197 | inst_type = SL_INTEGER; | ||
198 | size = (inst.M1.x6 & 0x3); | ||
199 | if ((inst.M1.x6 >> 2) > 0xb) { | ||
200 | /*write*/ | ||
201 | dir = IOREQ_WRITE; | ||
202 | data = vcpu_get_gr(vcpu, inst.M4.r2); | ||
203 | } else if ((inst.M1.x6 >> 2) < 0xb) { | ||
204 | /*read*/ | ||
205 | dir = IOREQ_READ; | ||
206 | } | ||
207 | } else if (inst.M2.major == 4 && inst.M2.m == 1 && inst.M2.x == 0) { | ||
208 | /* Integer Load + Reg update */ | ||
209 | inst_type = SL_INTEGER; | ||
210 | dir = IOREQ_READ; | ||
211 | size = (inst.M2.x6 & 0x3); | ||
212 | temp = vcpu_get_gr(vcpu, inst.M2.r3); | ||
213 | update_reg = vcpu_get_gr(vcpu, inst.M2.r2); | ||
214 | temp += update_reg; | ||
215 | vcpu_set_gr(vcpu, inst.M2.r3, temp, 0); | ||
216 | } else if (inst.M3.major == 5) { | ||
217 | /*Integer Load/Store + Imm update*/ | ||
218 | inst_type = SL_INTEGER; | ||
219 | size = (inst.M3.x6&0x3); | ||
220 | if ((inst.M5.x6 >> 2) > 0xb) { | ||
221 | /*write*/ | ||
222 | dir = IOREQ_WRITE; | ||
223 | data = vcpu_get_gr(vcpu, inst.M5.r2); | ||
224 | temp = vcpu_get_gr(vcpu, inst.M5.r3); | ||
225 | imm = (inst.M5.s << 31) | (inst.M5.i << 30) | | ||
226 | (inst.M5.imm7 << 23); | ||
227 | temp += imm >> 23; | ||
228 | vcpu_set_gr(vcpu, inst.M5.r3, temp, 0); | ||
229 | |||
230 | } else if ((inst.M3.x6 >> 2) < 0xb) { | ||
231 | /*read*/ | ||
232 | dir = IOREQ_READ; | ||
233 | temp = vcpu_get_gr(vcpu, inst.M3.r3); | ||
234 | imm = (inst.M3.s << 31) | (inst.M3.i << 30) | | ||
235 | (inst.M3.imm7 << 23); | ||
236 | temp += imm >> 23; | ||
237 | vcpu_set_gr(vcpu, inst.M3.r3, temp, 0); | ||
238 | |||
239 | } | ||
240 | } else if (inst.M9.major == 6 && inst.M9.x6 == 0x3B | ||
241 | && inst.M9.m == 0 && inst.M9.x == 0) { | ||
242 | /* Floating-point spill*/ | ||
243 | struct ia64_fpreg v; | ||
244 | |||
245 | inst_type = SL_FLOATING; | ||
246 | dir = IOREQ_WRITE; | ||
247 | vcpu_get_fpreg(vcpu, inst.M9.f2, &v); | ||
248 | /* Write high word. FIXME: this is a kludge! */ | ||
249 | v.u.bits[1] &= 0x3ffff; | ||
250 | mmio_access(vcpu, padr + 8, (u64 *)&v.u.bits[1], 8, | ||
251 | ma, IOREQ_WRITE); | ||
252 | data = v.u.bits[0]; | ||
253 | size = 3; | ||
254 | } else if (inst.M10.major == 7 && inst.M10.x6 == 0x3B) { | ||
255 | /* Floating-point spill + Imm update */ | ||
256 | struct ia64_fpreg v; | ||
257 | |||
258 | inst_type = SL_FLOATING; | ||
259 | dir = IOREQ_WRITE; | ||
260 | vcpu_get_fpreg(vcpu, inst.M10.f2, &v); | ||
261 | temp = vcpu_get_gr(vcpu, inst.M10.r3); | ||
262 | imm = (inst.M10.s << 31) | (inst.M10.i << 30) | | ||
263 | (inst.M10.imm7 << 23); | ||
264 | temp += imm >> 23; | ||
265 | vcpu_set_gr(vcpu, inst.M10.r3, temp, 0); | ||
266 | |||
267 | /* Write high word.FIXME: this is a kludge! */ | ||
268 | v.u.bits[1] &= 0x3ffff; | ||
269 | mmio_access(vcpu, padr + 8, (u64 *)&v.u.bits[1], | ||
270 | 8, ma, IOREQ_WRITE); | ||
271 | data = v.u.bits[0]; | ||
272 | size = 3; | ||
273 | } else if (inst.M10.major == 7 && inst.M10.x6 == 0x31) { | ||
274 | /* Floating-point stf8 + Imm update */ | ||
275 | struct ia64_fpreg v; | ||
276 | inst_type = SL_FLOATING; | ||
277 | dir = IOREQ_WRITE; | ||
278 | size = 3; | ||
279 | vcpu_get_fpreg(vcpu, inst.M10.f2, &v); | ||
280 | data = v.u.bits[0]; /* Significand. */ | ||
281 | temp = vcpu_get_gr(vcpu, inst.M10.r3); | ||
282 | imm = (inst.M10.s << 31) | (inst.M10.i << 30) | | ||
283 | (inst.M10.imm7 << 23); | ||
284 | temp += imm >> 23; | ||
285 | vcpu_set_gr(vcpu, inst.M10.r3, temp, 0); | ||
286 | } else if (inst.M15.major == 7 && inst.M15.x6 >= 0x2c | ||
287 | && inst.M15.x6 <= 0x2f) { | ||
288 | temp = vcpu_get_gr(vcpu, inst.M15.r3); | ||
289 | imm = (inst.M15.s << 31) | (inst.M15.i << 30) | | ||
290 | (inst.M15.imm7 << 23); | ||
291 | temp += imm >> 23; | ||
292 | vcpu_set_gr(vcpu, inst.M15.r3, temp, 0); | ||
293 | |||
294 | vcpu_increment_iip(vcpu); | ||
295 | return; | ||
296 | } else if (inst.M12.major == 6 && inst.M12.m == 1 | ||
297 | && inst.M12.x == 1 && inst.M12.x6 == 1) { | ||
298 | /* Floating-point Load Pair + Imm ldfp8 M12*/ | ||
299 | struct ia64_fpreg v; | ||
300 | |||
301 | inst_type = SL_FLOATING; | ||
302 | dir = IOREQ_READ; | ||
303 | size = 8; /*ldfd*/ | ||
304 | mmio_access(vcpu, padr, &data, size, ma, dir); | ||
305 | v.u.bits[0] = data; | ||
306 | v.u.bits[1] = 0x1003E; | ||
307 | vcpu_set_fpreg(vcpu, inst.M12.f1, &v); | ||
308 | padr += 8; | ||
309 | mmio_access(vcpu, padr, &data, size, ma, dir); | ||
310 | v.u.bits[0] = data; | ||
311 | v.u.bits[1] = 0x1003E; | ||
312 | vcpu_set_fpreg(vcpu, inst.M12.f2, &v); | ||
313 | padr += 8; | ||
314 | vcpu_set_gr(vcpu, inst.M12.r3, padr, 0); | ||
315 | vcpu_increment_iip(vcpu); | ||
316 | return; | ||
317 | } else { | ||
318 | inst_type = -1; | ||
319 | panic_vm(vcpu, "Unsupported MMIO access instruction! " | ||
320 | "Bunld[0]=0x%lx, Bundle[1]=0x%lx\n", | ||
321 | bundle.i64[0], bundle.i64[1]); | ||
322 | } | ||
323 | |||
324 | size = 1 << size; | ||
325 | if (dir == IOREQ_WRITE) { | ||
326 | mmio_access(vcpu, padr, &data, size, ma, dir); | ||
327 | } else { | ||
328 | mmio_access(vcpu, padr, &data, size, ma, dir); | ||
329 | if (inst_type == SL_INTEGER) | ||
330 | vcpu_set_gr(vcpu, inst.M1.r1, data, 0); | ||
331 | else | ||
332 | panic_vm(vcpu, "Unsupported instruction type!\n"); | ||
333 | |||
334 | } | ||
335 | vcpu_increment_iip(vcpu); | ||
336 | } | ||
diff --git a/arch/ia64/kvm/optvfault.S b/arch/ia64/kvm/optvfault.S deleted file mode 100644 index f793be3effff..000000000000 --- a/arch/ia64/kvm/optvfault.S +++ /dev/null | |||
@@ -1,1090 +0,0 @@ | |||
1 | /* | ||
2 | * arch/ia64/kvm/optvfault.S | ||
3 | * optimize virtualization fault handler | ||
4 | * | ||
5 | * Copyright (C) 2006 Intel Co | ||
6 | * Xuefei Xu (Anthony Xu) <anthony.xu@intel.com> | ||
7 | * Copyright (C) 2008 Intel Co | ||
8 | * Add the support for Tukwila processors. | ||
9 | * Xiantao Zhang <xiantao.zhang@intel.com> | ||
10 | */ | ||
11 | |||
12 | #include <asm/asmmacro.h> | ||
13 | #include <asm/processor.h> | ||
14 | #include <asm/kvm_host.h> | ||
15 | |||
16 | #include "vti.h" | ||
17 | #include "asm-offsets.h" | ||
18 | |||
19 | #define ACCE_MOV_FROM_AR | ||
20 | #define ACCE_MOV_FROM_RR | ||
21 | #define ACCE_MOV_TO_RR | ||
22 | #define ACCE_RSM | ||
23 | #define ACCE_SSM | ||
24 | #define ACCE_MOV_TO_PSR | ||
25 | #define ACCE_THASH | ||
26 | |||
27 | #define VMX_VPS_SYNC_READ \ | ||
28 | add r16=VMM_VPD_BASE_OFFSET,r21; \ | ||
29 | mov r17 = b0; \ | ||
30 | mov r18 = r24; \ | ||
31 | mov r19 = r25; \ | ||
32 | mov r20 = r31; \ | ||
33 | ;; \ | ||
34 | {.mii; \ | ||
35 | ld8 r16 = [r16]; \ | ||
36 | nop 0x0; \ | ||
37 | mov r24 = ip; \ | ||
38 | ;; \ | ||
39 | }; \ | ||
40 | {.mmb; \ | ||
41 | add r24=0x20, r24; \ | ||
42 | mov r25 =r16; \ | ||
43 | br.sptk.many kvm_vps_sync_read; \ | ||
44 | }; \ | ||
45 | mov b0 = r17; \ | ||
46 | mov r24 = r18; \ | ||
47 | mov r25 = r19; \ | ||
48 | mov r31 = r20 | ||
49 | |||
50 | ENTRY(kvm_vps_entry) | ||
51 | adds r29 = VMM_VCPU_VSA_BASE_OFFSET,r21 | ||
52 | ;; | ||
53 | ld8 r29 = [r29] | ||
54 | ;; | ||
55 | add r29 = r29, r30 | ||
56 | ;; | ||
57 | mov b0 = r29 | ||
58 | br.sptk.many b0 | ||
59 | END(kvm_vps_entry) | ||
60 | |||
61 | /* | ||
62 | * Inputs: | ||
63 | * r24 : return address | ||
64 | * r25 : vpd | ||
65 | * r29 : scratch | ||
66 | * | ||
67 | */ | ||
68 | GLOBAL_ENTRY(kvm_vps_sync_read) | ||
69 | movl r30 = PAL_VPS_SYNC_READ | ||
70 | ;; | ||
71 | br.sptk.many kvm_vps_entry | ||
72 | END(kvm_vps_sync_read) | ||
73 | |||
74 | /* | ||
75 | * Inputs: | ||
76 | * r24 : return address | ||
77 | * r25 : vpd | ||
78 | * r29 : scratch | ||
79 | * | ||
80 | */ | ||
81 | GLOBAL_ENTRY(kvm_vps_sync_write) | ||
82 | movl r30 = PAL_VPS_SYNC_WRITE | ||
83 | ;; | ||
84 | br.sptk.many kvm_vps_entry | ||
85 | END(kvm_vps_sync_write) | ||
86 | |||
87 | /* | ||
88 | * Inputs: | ||
89 | * r23 : pr | ||
90 | * r24 : guest b0 | ||
91 | * r25 : vpd | ||
92 | * | ||
93 | */ | ||
94 | GLOBAL_ENTRY(kvm_vps_resume_normal) | ||
95 | movl r30 = PAL_VPS_RESUME_NORMAL | ||
96 | ;; | ||
97 | mov pr=r23,-2 | ||
98 | br.sptk.many kvm_vps_entry | ||
99 | END(kvm_vps_resume_normal) | ||
100 | |||
101 | /* | ||
102 | * Inputs: | ||
103 | * r23 : pr | ||
104 | * r24 : guest b0 | ||
105 | * r25 : vpd | ||
106 | * r17 : isr | ||
107 | */ | ||
108 | GLOBAL_ENTRY(kvm_vps_resume_handler) | ||
109 | movl r30 = PAL_VPS_RESUME_HANDLER | ||
110 | ;; | ||
111 | ld8 r26=[r25] | ||
112 | shr r17=r17,IA64_ISR_IR_BIT | ||
113 | ;; | ||
114 | dep r26=r17,r26,63,1 // bit 63 of r26 indicate whether enable CFLE | ||
115 | mov pr=r23,-2 | ||
116 | br.sptk.many kvm_vps_entry | ||
117 | END(kvm_vps_resume_handler) | ||
118 | |||
119 | //mov r1=ar3 | ||
120 | GLOBAL_ENTRY(kvm_asm_mov_from_ar) | ||
121 | #ifndef ACCE_MOV_FROM_AR | ||
122 | br.many kvm_virtualization_fault_back | ||
123 | #endif | ||
124 | add r18=VMM_VCPU_ITC_OFS_OFFSET, r21 | ||
125 | add r16=VMM_VCPU_LAST_ITC_OFFSET,r21 | ||
126 | extr.u r17=r25,6,7 | ||
127 | ;; | ||
128 | ld8 r18=[r18] | ||
129 | mov r19=ar.itc | ||
130 | mov r24=b0 | ||
131 | ;; | ||
132 | add r19=r19,r18 | ||
133 | addl r20=@gprel(asm_mov_to_reg),gp | ||
134 | ;; | ||
135 | st8 [r16] = r19 | ||
136 | adds r30=kvm_resume_to_guest-asm_mov_to_reg,r20 | ||
137 | shladd r17=r17,4,r20 | ||
138 | ;; | ||
139 | mov b0=r17 | ||
140 | br.sptk.few b0 | ||
141 | ;; | ||
142 | END(kvm_asm_mov_from_ar) | ||
143 | |||
144 | /* | ||
145 | * Special SGI SN2 optimized version of mov_from_ar using the SN2 RTC | ||
146 | * clock as it's source for emulating the ITC. This version will be | ||
147 | * copied on top of the original version if the host is determined to | ||
148 | * be an SN2. | ||
149 | */ | ||
150 | GLOBAL_ENTRY(kvm_asm_mov_from_ar_sn2) | ||
151 | add r18=VMM_VCPU_ITC_OFS_OFFSET, r21 | ||
152 | movl r19 = (KVM_VMM_BASE+(1<<KVM_VMM_SHIFT)) | ||
153 | |||
154 | add r16=VMM_VCPU_LAST_ITC_OFFSET,r21 | ||
155 | extr.u r17=r25,6,7 | ||
156 | mov r24=b0 | ||
157 | ;; | ||
158 | ld8 r18=[r18] | ||
159 | ld8 r19=[r19] | ||
160 | addl r20=@gprel(asm_mov_to_reg),gp | ||
161 | ;; | ||
162 | add r19=r19,r18 | ||
163 | shladd r17=r17,4,r20 | ||
164 | ;; | ||
165 | adds r30=kvm_resume_to_guest-asm_mov_to_reg,r20 | ||
166 | st8 [r16] = r19 | ||
167 | mov b0=r17 | ||
168 | br.sptk.few b0 | ||
169 | ;; | ||
170 | END(kvm_asm_mov_from_ar_sn2) | ||
171 | |||
172 | |||
173 | |||
174 | // mov r1=rr[r3] | ||
175 | GLOBAL_ENTRY(kvm_asm_mov_from_rr) | ||
176 | #ifndef ACCE_MOV_FROM_RR | ||
177 | br.many kvm_virtualization_fault_back | ||
178 | #endif | ||
179 | extr.u r16=r25,20,7 | ||
180 | extr.u r17=r25,6,7 | ||
181 | addl r20=@gprel(asm_mov_from_reg),gp | ||
182 | ;; | ||
183 | adds r30=kvm_asm_mov_from_rr_back_1-asm_mov_from_reg,r20 | ||
184 | shladd r16=r16,4,r20 | ||
185 | mov r24=b0 | ||
186 | ;; | ||
187 | add r27=VMM_VCPU_VRR0_OFFSET,r21 | ||
188 | mov b0=r16 | ||
189 | br.many b0 | ||
190 | ;; | ||
191 | kvm_asm_mov_from_rr_back_1: | ||
192 | adds r30=kvm_resume_to_guest-asm_mov_from_reg,r20 | ||
193 | adds r22=asm_mov_to_reg-asm_mov_from_reg,r20 | ||
194 | shr.u r26=r19,61 | ||
195 | ;; | ||
196 | shladd r17=r17,4,r22 | ||
197 | shladd r27=r26,3,r27 | ||
198 | ;; | ||
199 | ld8 r19=[r27] | ||
200 | mov b0=r17 | ||
201 | br.many b0 | ||
202 | END(kvm_asm_mov_from_rr) | ||
203 | |||
204 | |||
205 | // mov rr[r3]=r2 | ||
206 | GLOBAL_ENTRY(kvm_asm_mov_to_rr) | ||
207 | #ifndef ACCE_MOV_TO_RR | ||
208 | br.many kvm_virtualization_fault_back | ||
209 | #endif | ||
210 | extr.u r16=r25,20,7 | ||
211 | extr.u r17=r25,13,7 | ||
212 | addl r20=@gprel(asm_mov_from_reg),gp | ||
213 | ;; | ||
214 | adds r30=kvm_asm_mov_to_rr_back_1-asm_mov_from_reg,r20 | ||
215 | shladd r16=r16,4,r20 | ||
216 | mov r22=b0 | ||
217 | ;; | ||
218 | add r27=VMM_VCPU_VRR0_OFFSET,r21 | ||
219 | mov b0=r16 | ||
220 | br.many b0 | ||
221 | ;; | ||
222 | kvm_asm_mov_to_rr_back_1: | ||
223 | adds r30=kvm_asm_mov_to_rr_back_2-asm_mov_from_reg,r20 | ||
224 | shr.u r23=r19,61 | ||
225 | shladd r17=r17,4,r20 | ||
226 | ;; | ||
227 | //if rr6, go back | ||
228 | cmp.eq p6,p0=6,r23 | ||
229 | mov b0=r22 | ||
230 | (p6) br.cond.dpnt.many kvm_virtualization_fault_back | ||
231 | ;; | ||
232 | mov r28=r19 | ||
233 | mov b0=r17 | ||
234 | br.many b0 | ||
235 | kvm_asm_mov_to_rr_back_2: | ||
236 | adds r30=kvm_resume_to_guest-asm_mov_from_reg,r20 | ||
237 | shladd r27=r23,3,r27 | ||
238 | ;; // vrr.rid<<4 |0xe | ||
239 | st8 [r27]=r19 | ||
240 | mov b0=r30 | ||
241 | ;; | ||
242 | extr.u r16=r19,8,26 | ||
243 | extr.u r18 =r19,2,6 | ||
244 | mov r17 =0xe | ||
245 | ;; | ||
246 | shladd r16 = r16, 4, r17 | ||
247 | extr.u r19 =r19,0,8 | ||
248 | ;; | ||
249 | shl r16 = r16,8 | ||
250 | ;; | ||
251 | add r19 = r19, r16 | ||
252 | ;; //set ve 1 | ||
253 | dep r19=-1,r19,0,1 | ||
254 | cmp.lt p6,p0=14,r18 | ||
255 | ;; | ||
256 | (p6) mov r18=14 | ||
257 | ;; | ||
258 | (p6) dep r19=r18,r19,2,6 | ||
259 | ;; | ||
260 | cmp.eq p6,p0=0,r23 | ||
261 | ;; | ||
262 | cmp.eq.or p6,p0=4,r23 | ||
263 | ;; | ||
264 | adds r16=VMM_VCPU_MODE_FLAGS_OFFSET,r21 | ||
265 | (p6) adds r17=VMM_VCPU_META_SAVED_RR0_OFFSET,r21 | ||
266 | ;; | ||
267 | ld4 r16=[r16] | ||
268 | cmp.eq p7,p0=r0,r0 | ||
269 | (p6) shladd r17=r23,1,r17 | ||
270 | ;; | ||
271 | (p6) st8 [r17]=r19 | ||
272 | (p6) tbit.nz p6,p7=r16,0 | ||
273 | ;; | ||
274 | (p7) mov rr[r28]=r19 | ||
275 | mov r24=r22 | ||
276 | br.many b0 | ||
277 | END(kvm_asm_mov_to_rr) | ||
278 | |||
279 | |||
280 | //rsm | ||
281 | GLOBAL_ENTRY(kvm_asm_rsm) | ||
282 | #ifndef ACCE_RSM | ||
283 | br.many kvm_virtualization_fault_back | ||
284 | #endif | ||
285 | VMX_VPS_SYNC_READ | ||
286 | ;; | ||
287 | extr.u r26=r25,6,21 | ||
288 | extr.u r27=r25,31,2 | ||
289 | ;; | ||
290 | extr.u r28=r25,36,1 | ||
291 | dep r26=r27,r26,21,2 | ||
292 | ;; | ||
293 | add r17=VPD_VPSR_START_OFFSET,r16 | ||
294 | add r22=VMM_VCPU_MODE_FLAGS_OFFSET,r21 | ||
295 | //r26 is imm24 | ||
296 | dep r26=r28,r26,23,1 | ||
297 | ;; | ||
298 | ld8 r18=[r17] | ||
299 | movl r28=IA64_PSR_IC+IA64_PSR_I+IA64_PSR_DT+IA64_PSR_SI | ||
300 | ld4 r23=[r22] | ||
301 | sub r27=-1,r26 | ||
302 | mov r24=b0 | ||
303 | ;; | ||
304 | mov r20=cr.ipsr | ||
305 | or r28=r27,r28 | ||
306 | and r19=r18,r27 | ||
307 | ;; | ||
308 | st8 [r17]=r19 | ||
309 | and r20=r20,r28 | ||
310 | /* Comment it out due to short of fp lazy alorgithm support | ||
311 | adds r27=IA64_VCPU_FP_PSR_OFFSET,r21 | ||
312 | ;; | ||
313 | ld8 r27=[r27] | ||
314 | ;; | ||
315 | tbit.nz p8,p0= r27,IA64_PSR_DFH_BIT | ||
316 | ;; | ||
317 | (p8) dep r20=-1,r20,IA64_PSR_DFH_BIT,1 | ||
318 | */ | ||
319 | ;; | ||
320 | mov cr.ipsr=r20 | ||
321 | tbit.nz p6,p0=r23,0 | ||
322 | ;; | ||
323 | tbit.z.or p6,p0=r26,IA64_PSR_DT_BIT | ||
324 | (p6) br.dptk kvm_resume_to_guest_with_sync | ||
325 | ;; | ||
326 | add r26=VMM_VCPU_META_RR0_OFFSET,r21 | ||
327 | add r27=VMM_VCPU_META_RR0_OFFSET+8,r21 | ||
328 | dep r23=-1,r23,0,1 | ||
329 | ;; | ||
330 | ld8 r26=[r26] | ||
331 | ld8 r27=[r27] | ||
332 | st4 [r22]=r23 | ||
333 | dep.z r28=4,61,3 | ||
334 | ;; | ||
335 | mov rr[r0]=r26 | ||
336 | ;; | ||
337 | mov rr[r28]=r27 | ||
338 | ;; | ||
339 | srlz.d | ||
340 | br.many kvm_resume_to_guest_with_sync | ||
341 | END(kvm_asm_rsm) | ||
342 | |||
343 | |||
344 | //ssm | ||
345 | GLOBAL_ENTRY(kvm_asm_ssm) | ||
346 | #ifndef ACCE_SSM | ||
347 | br.many kvm_virtualization_fault_back | ||
348 | #endif | ||
349 | VMX_VPS_SYNC_READ | ||
350 | ;; | ||
351 | extr.u r26=r25,6,21 | ||
352 | extr.u r27=r25,31,2 | ||
353 | ;; | ||
354 | extr.u r28=r25,36,1 | ||
355 | dep r26=r27,r26,21,2 | ||
356 | ;; //r26 is imm24 | ||
357 | add r27=VPD_VPSR_START_OFFSET,r16 | ||
358 | dep r26=r28,r26,23,1 | ||
359 | ;; //r19 vpsr | ||
360 | ld8 r29=[r27] | ||
361 | mov r24=b0 | ||
362 | ;; | ||
363 | add r22=VMM_VCPU_MODE_FLAGS_OFFSET,r21 | ||
364 | mov r20=cr.ipsr | ||
365 | or r19=r29,r26 | ||
366 | ;; | ||
367 | ld4 r23=[r22] | ||
368 | st8 [r27]=r19 | ||
369 | or r20=r20,r26 | ||
370 | ;; | ||
371 | mov cr.ipsr=r20 | ||
372 | movl r28=IA64_PSR_DT+IA64_PSR_RT+IA64_PSR_IT | ||
373 | ;; | ||
374 | and r19=r28,r19 | ||
375 | tbit.z p6,p0=r23,0 | ||
376 | ;; | ||
377 | cmp.ne.or p6,p0=r28,r19 | ||
378 | (p6) br.dptk kvm_asm_ssm_1 | ||
379 | ;; | ||
380 | add r26=VMM_VCPU_META_SAVED_RR0_OFFSET,r21 | ||
381 | add r27=VMM_VCPU_META_SAVED_RR0_OFFSET+8,r21 | ||
382 | dep r23=0,r23,0,1 | ||
383 | ;; | ||
384 | ld8 r26=[r26] | ||
385 | ld8 r27=[r27] | ||
386 | st4 [r22]=r23 | ||
387 | dep.z r28=4,61,3 | ||
388 | ;; | ||
389 | mov rr[r0]=r26 | ||
390 | ;; | ||
391 | mov rr[r28]=r27 | ||
392 | ;; | ||
393 | srlz.d | ||
394 | ;; | ||
395 | kvm_asm_ssm_1: | ||
396 | tbit.nz p6,p0=r29,IA64_PSR_I_BIT | ||
397 | ;; | ||
398 | tbit.z.or p6,p0=r19,IA64_PSR_I_BIT | ||
399 | (p6) br.dptk kvm_resume_to_guest_with_sync | ||
400 | ;; | ||
401 | add r29=VPD_VTPR_START_OFFSET,r16 | ||
402 | add r30=VPD_VHPI_START_OFFSET,r16 | ||
403 | ;; | ||
404 | ld8 r29=[r29] | ||
405 | ld8 r30=[r30] | ||
406 | ;; | ||
407 | extr.u r17=r29,4,4 | ||
408 | extr.u r18=r29,16,1 | ||
409 | ;; | ||
410 | dep r17=r18,r17,4,1 | ||
411 | ;; | ||
412 | cmp.gt p6,p0=r30,r17 | ||
413 | (p6) br.dpnt.few kvm_asm_dispatch_vexirq | ||
414 | br.many kvm_resume_to_guest_with_sync | ||
415 | END(kvm_asm_ssm) | ||
416 | |||
417 | |||
418 | //mov psr.l=r2 | ||
419 | GLOBAL_ENTRY(kvm_asm_mov_to_psr) | ||
420 | #ifndef ACCE_MOV_TO_PSR | ||
421 | br.many kvm_virtualization_fault_back | ||
422 | #endif | ||
423 | VMX_VPS_SYNC_READ | ||
424 | ;; | ||
425 | extr.u r26=r25,13,7 //r2 | ||
426 | addl r20=@gprel(asm_mov_from_reg),gp | ||
427 | ;; | ||
428 | adds r30=kvm_asm_mov_to_psr_back-asm_mov_from_reg,r20 | ||
429 | shladd r26=r26,4,r20 | ||
430 | mov r24=b0 | ||
431 | ;; | ||
432 | add r27=VPD_VPSR_START_OFFSET,r16 | ||
433 | mov b0=r26 | ||
434 | br.many b0 | ||
435 | ;; | ||
436 | kvm_asm_mov_to_psr_back: | ||
437 | ld8 r17=[r27] | ||
438 | add r22=VMM_VCPU_MODE_FLAGS_OFFSET,r21 | ||
439 | dep r19=0,r19,32,32 | ||
440 | ;; | ||
441 | ld4 r23=[r22] | ||
442 | dep r18=0,r17,0,32 | ||
443 | ;; | ||
444 | add r30=r18,r19 | ||
445 | movl r28=IA64_PSR_DT+IA64_PSR_RT+IA64_PSR_IT | ||
446 | ;; | ||
447 | st8 [r27]=r30 | ||
448 | and r27=r28,r30 | ||
449 | and r29=r28,r17 | ||
450 | ;; | ||
451 | cmp.eq p5,p0=r29,r27 | ||
452 | cmp.eq p6,p7=r28,r27 | ||
453 | (p5) br.many kvm_asm_mov_to_psr_1 | ||
454 | ;; | ||
455 | //virtual to physical | ||
456 | (p7) add r26=VMM_VCPU_META_RR0_OFFSET,r21 | ||
457 | (p7) add r27=VMM_VCPU_META_RR0_OFFSET+8,r21 | ||
458 | (p7) dep r23=-1,r23,0,1 | ||
459 | ;; | ||
460 | //physical to virtual | ||
461 | (p6) add r26=VMM_VCPU_META_SAVED_RR0_OFFSET,r21 | ||
462 | (p6) add r27=VMM_VCPU_META_SAVED_RR0_OFFSET+8,r21 | ||
463 | (p6) dep r23=0,r23,0,1 | ||
464 | ;; | ||
465 | ld8 r26=[r26] | ||
466 | ld8 r27=[r27] | ||
467 | st4 [r22]=r23 | ||
468 | dep.z r28=4,61,3 | ||
469 | ;; | ||
470 | mov rr[r0]=r26 | ||
471 | ;; | ||
472 | mov rr[r28]=r27 | ||
473 | ;; | ||
474 | srlz.d | ||
475 | ;; | ||
476 | kvm_asm_mov_to_psr_1: | ||
477 | mov r20=cr.ipsr | ||
478 | movl r28=IA64_PSR_IC+IA64_PSR_I+IA64_PSR_DT+IA64_PSR_SI+IA64_PSR_RT | ||
479 | ;; | ||
480 | or r19=r19,r28 | ||
481 | dep r20=0,r20,0,32 | ||
482 | ;; | ||
483 | add r20=r19,r20 | ||
484 | mov b0=r24 | ||
485 | ;; | ||
486 | /* Comment it out due to short of fp lazy algorithm support | ||
487 | adds r27=IA64_VCPU_FP_PSR_OFFSET,r21 | ||
488 | ;; | ||
489 | ld8 r27=[r27] | ||
490 | ;; | ||
491 | tbit.nz p8,p0=r27,IA64_PSR_DFH_BIT | ||
492 | ;; | ||
493 | (p8) dep r20=-1,r20,IA64_PSR_DFH_BIT,1 | ||
494 | ;; | ||
495 | */ | ||
496 | mov cr.ipsr=r20 | ||
497 | cmp.ne p6,p0=r0,r0 | ||
498 | ;; | ||
499 | tbit.nz.or p6,p0=r17,IA64_PSR_I_BIT | ||
500 | tbit.z.or p6,p0=r30,IA64_PSR_I_BIT | ||
501 | (p6) br.dpnt.few kvm_resume_to_guest_with_sync | ||
502 | ;; | ||
503 | add r29=VPD_VTPR_START_OFFSET,r16 | ||
504 | add r30=VPD_VHPI_START_OFFSET,r16 | ||
505 | ;; | ||
506 | ld8 r29=[r29] | ||
507 | ld8 r30=[r30] | ||
508 | ;; | ||
509 | extr.u r17=r29,4,4 | ||
510 | extr.u r18=r29,16,1 | ||
511 | ;; | ||
512 | dep r17=r18,r17,4,1 | ||
513 | ;; | ||
514 | cmp.gt p6,p0=r30,r17 | ||
515 | (p6) br.dpnt.few kvm_asm_dispatch_vexirq | ||
516 | br.many kvm_resume_to_guest_with_sync | ||
517 | END(kvm_asm_mov_to_psr) | ||
518 | |||
519 | |||
520 | ENTRY(kvm_asm_dispatch_vexirq) | ||
521 | //increment iip | ||
522 | mov r17 = b0 | ||
523 | mov r18 = r31 | ||
524 | {.mii | ||
525 | add r25=VMM_VPD_BASE_OFFSET,r21 | ||
526 | nop 0x0 | ||
527 | mov r24 = ip | ||
528 | ;; | ||
529 | } | ||
530 | {.mmb | ||
531 | add r24 = 0x20, r24 | ||
532 | ld8 r25 = [r25] | ||
533 | br.sptk.many kvm_vps_sync_write | ||
534 | } | ||
535 | mov b0 =r17 | ||
536 | mov r16=cr.ipsr | ||
537 | mov r31 = r18 | ||
538 | mov r19 = 37 | ||
539 | ;; | ||
540 | extr.u r17=r16,IA64_PSR_RI_BIT,2 | ||
541 | tbit.nz p6,p7=r16,IA64_PSR_RI_BIT+1 | ||
542 | ;; | ||
543 | (p6) mov r18=cr.iip | ||
544 | (p6) mov r17=r0 | ||
545 | (p7) add r17=1,r17 | ||
546 | ;; | ||
547 | (p6) add r18=0x10,r18 | ||
548 | dep r16=r17,r16,IA64_PSR_RI_BIT,2 | ||
549 | ;; | ||
550 | (p6) mov cr.iip=r18 | ||
551 | mov cr.ipsr=r16 | ||
552 | mov r30 =1 | ||
553 | br.many kvm_dispatch_vexirq | ||
554 | END(kvm_asm_dispatch_vexirq) | ||
555 | |||
556 | // thash | ||
557 | // TODO: add support when pta.vf = 1 | ||
558 | GLOBAL_ENTRY(kvm_asm_thash) | ||
559 | #ifndef ACCE_THASH | ||
560 | br.many kvm_virtualization_fault_back | ||
561 | #endif | ||
562 | extr.u r17=r25,20,7 // get r3 from opcode in r25 | ||
563 | extr.u r18=r25,6,7 // get r1 from opcode in r25 | ||
564 | addl r20=@gprel(asm_mov_from_reg),gp | ||
565 | ;; | ||
566 | adds r30=kvm_asm_thash_back1-asm_mov_from_reg,r20 | ||
567 | shladd r17=r17,4,r20 // get addr of MOVE_FROM_REG(r17) | ||
568 | adds r16=VMM_VPD_BASE_OFFSET,r21 // get vcpu.arch.priveregs | ||
569 | ;; | ||
570 | mov r24=b0 | ||
571 | ;; | ||
572 | ld8 r16=[r16] // get VPD addr | ||
573 | mov b0=r17 | ||
574 | br.many b0 // r19 return value | ||
575 | ;; | ||
576 | kvm_asm_thash_back1: | ||
577 | shr.u r23=r19,61 // get RR number | ||
578 | adds r28=VMM_VCPU_VRR0_OFFSET,r21 // get vcpu->arch.vrr[0]'s addr | ||
579 | adds r16=VMM_VPD_VPTA_OFFSET,r16 // get vpta | ||
580 | ;; | ||
581 | shladd r27=r23,3,r28 // get vcpu->arch.vrr[r23]'s addr | ||
582 | ld8 r17=[r16] // get PTA | ||
583 | mov r26=1 | ||
584 | ;; | ||
585 | extr.u r29=r17,2,6 // get pta.size | ||
586 | ld8 r28=[r27] // get vcpu->arch.vrr[r23]'s value | ||
587 | ;; | ||
588 | mov b0=r24 | ||
589 | //Fallback to C if pta.vf is set | ||
590 | tbit.nz p6,p0=r17, 8 | ||
591 | ;; | ||
592 | (p6) mov r24=EVENT_THASH | ||
593 | (p6) br.cond.dpnt.many kvm_virtualization_fault_back | ||
594 | extr.u r28=r28,2,6 // get rr.ps | ||
595 | shl r22=r26,r29 // 1UL << pta.size | ||
596 | ;; | ||
597 | shr.u r23=r19,r28 // vaddr >> rr.ps | ||
598 | adds r26=3,r29 // pta.size + 3 | ||
599 | shl r27=r17,3 // pta << 3 | ||
600 | ;; | ||
601 | shl r23=r23,3 // (vaddr >> rr.ps) << 3 | ||
602 | shr.u r27=r27,r26 // (pta << 3) >> (pta.size+3) | ||
603 | movl r16=7<<61 | ||
604 | ;; | ||
605 | adds r22=-1,r22 // (1UL << pta.size) - 1 | ||
606 | shl r27=r27,r29 // ((pta<<3)>>(pta.size+3))<<pta.size | ||
607 | and r19=r19,r16 // vaddr & VRN_MASK | ||
608 | ;; | ||
609 | and r22=r22,r23 // vhpt_offset | ||
610 | or r19=r19,r27 // (vadr&VRN_MASK)|(((pta<<3)>>(pta.size + 3))<<pta.size) | ||
611 | adds r26=asm_mov_to_reg-asm_mov_from_reg,r20 | ||
612 | ;; | ||
613 | or r19=r19,r22 // calc pval | ||
614 | shladd r17=r18,4,r26 | ||
615 | adds r30=kvm_resume_to_guest-asm_mov_from_reg,r20 | ||
616 | ;; | ||
617 | mov b0=r17 | ||
618 | br.many b0 | ||
619 | END(kvm_asm_thash) | ||
620 | |||
621 | #define MOV_TO_REG0 \ | ||
622 | {; \ | ||
623 | nop.b 0x0; \ | ||
624 | nop.b 0x0; \ | ||
625 | nop.b 0x0; \ | ||
626 | ;; \ | ||
627 | }; | ||
628 | |||
629 | |||
630 | #define MOV_TO_REG(n) \ | ||
631 | {; \ | ||
632 | mov r##n##=r19; \ | ||
633 | mov b0=r30; \ | ||
634 | br.sptk.many b0; \ | ||
635 | ;; \ | ||
636 | }; | ||
637 | |||
638 | |||
639 | #define MOV_FROM_REG(n) \ | ||
640 | {; \ | ||
641 | mov r19=r##n##; \ | ||
642 | mov b0=r30; \ | ||
643 | br.sptk.many b0; \ | ||
644 | ;; \ | ||
645 | }; | ||
646 | |||
647 | |||
648 | #define MOV_TO_BANK0_REG(n) \ | ||
649 | ENTRY_MIN_ALIGN(asm_mov_to_bank0_reg##n##); \ | ||
650 | {; \ | ||
651 | mov r26=r2; \ | ||
652 | mov r2=r19; \ | ||
653 | bsw.1; \ | ||
654 | ;; \ | ||
655 | }; \ | ||
656 | {; \ | ||
657 | mov r##n##=r2; \ | ||
658 | nop.b 0x0; \ | ||
659 | bsw.0; \ | ||
660 | ;; \ | ||
661 | }; \ | ||
662 | {; \ | ||
663 | mov r2=r26; \ | ||
664 | mov b0=r30; \ | ||
665 | br.sptk.many b0; \ | ||
666 | ;; \ | ||
667 | }; \ | ||
668 | END(asm_mov_to_bank0_reg##n##) | ||
669 | |||
670 | |||
671 | #define MOV_FROM_BANK0_REG(n) \ | ||
672 | ENTRY_MIN_ALIGN(asm_mov_from_bank0_reg##n##); \ | ||
673 | {; \ | ||
674 | mov r26=r2; \ | ||
675 | nop.b 0x0; \ | ||
676 | bsw.1; \ | ||
677 | ;; \ | ||
678 | }; \ | ||
679 | {; \ | ||
680 | mov r2=r##n##; \ | ||
681 | nop.b 0x0; \ | ||
682 | bsw.0; \ | ||
683 | ;; \ | ||
684 | }; \ | ||
685 | {; \ | ||
686 | mov r19=r2; \ | ||
687 | mov r2=r26; \ | ||
688 | mov b0=r30; \ | ||
689 | }; \ | ||
690 | {; \ | ||
691 | nop.b 0x0; \ | ||
692 | nop.b 0x0; \ | ||
693 | br.sptk.many b0; \ | ||
694 | ;; \ | ||
695 | }; \ | ||
696 | END(asm_mov_from_bank0_reg##n##) | ||
697 | |||
698 | |||
699 | #define JMP_TO_MOV_TO_BANK0_REG(n) \ | ||
700 | {; \ | ||
701 | nop.b 0x0; \ | ||
702 | nop.b 0x0; \ | ||
703 | br.sptk.many asm_mov_to_bank0_reg##n##; \ | ||
704 | ;; \ | ||
705 | } | ||
706 | |||
707 | |||
708 | #define JMP_TO_MOV_FROM_BANK0_REG(n) \ | ||
709 | {; \ | ||
710 | nop.b 0x0; \ | ||
711 | nop.b 0x0; \ | ||
712 | br.sptk.many asm_mov_from_bank0_reg##n##; \ | ||
713 | ;; \ | ||
714 | } | ||
715 | |||
716 | |||
717 | MOV_FROM_BANK0_REG(16) | ||
718 | MOV_FROM_BANK0_REG(17) | ||
719 | MOV_FROM_BANK0_REG(18) | ||
720 | MOV_FROM_BANK0_REG(19) | ||
721 | MOV_FROM_BANK0_REG(20) | ||
722 | MOV_FROM_BANK0_REG(21) | ||
723 | MOV_FROM_BANK0_REG(22) | ||
724 | MOV_FROM_BANK0_REG(23) | ||
725 | MOV_FROM_BANK0_REG(24) | ||
726 | MOV_FROM_BANK0_REG(25) | ||
727 | MOV_FROM_BANK0_REG(26) | ||
728 | MOV_FROM_BANK0_REG(27) | ||
729 | MOV_FROM_BANK0_REG(28) | ||
730 | MOV_FROM_BANK0_REG(29) | ||
731 | MOV_FROM_BANK0_REG(30) | ||
732 | MOV_FROM_BANK0_REG(31) | ||
733 | |||
734 | |||
735 | // mov from reg table | ||
736 | ENTRY(asm_mov_from_reg) | ||
737 | MOV_FROM_REG(0) | ||
738 | MOV_FROM_REG(1) | ||
739 | MOV_FROM_REG(2) | ||
740 | MOV_FROM_REG(3) | ||
741 | MOV_FROM_REG(4) | ||
742 | MOV_FROM_REG(5) | ||
743 | MOV_FROM_REG(6) | ||
744 | MOV_FROM_REG(7) | ||
745 | MOV_FROM_REG(8) | ||
746 | MOV_FROM_REG(9) | ||
747 | MOV_FROM_REG(10) | ||
748 | MOV_FROM_REG(11) | ||
749 | MOV_FROM_REG(12) | ||
750 | MOV_FROM_REG(13) | ||
751 | MOV_FROM_REG(14) | ||
752 | MOV_FROM_REG(15) | ||
753 | JMP_TO_MOV_FROM_BANK0_REG(16) | ||
754 | JMP_TO_MOV_FROM_BANK0_REG(17) | ||
755 | JMP_TO_MOV_FROM_BANK0_REG(18) | ||
756 | JMP_TO_MOV_FROM_BANK0_REG(19) | ||
757 | JMP_TO_MOV_FROM_BANK0_REG(20) | ||
758 | JMP_TO_MOV_FROM_BANK0_REG(21) | ||
759 | JMP_TO_MOV_FROM_BANK0_REG(22) | ||
760 | JMP_TO_MOV_FROM_BANK0_REG(23) | ||
761 | JMP_TO_MOV_FROM_BANK0_REG(24) | ||
762 | JMP_TO_MOV_FROM_BANK0_REG(25) | ||
763 | JMP_TO_MOV_FROM_BANK0_REG(26) | ||
764 | JMP_TO_MOV_FROM_BANK0_REG(27) | ||
765 | JMP_TO_MOV_FROM_BANK0_REG(28) | ||
766 | JMP_TO_MOV_FROM_BANK0_REG(29) | ||
767 | JMP_TO_MOV_FROM_BANK0_REG(30) | ||
768 | JMP_TO_MOV_FROM_BANK0_REG(31) | ||
769 | MOV_FROM_REG(32) | ||
770 | MOV_FROM_REG(33) | ||
771 | MOV_FROM_REG(34) | ||
772 | MOV_FROM_REG(35) | ||
773 | MOV_FROM_REG(36) | ||
774 | MOV_FROM_REG(37) | ||
775 | MOV_FROM_REG(38) | ||
776 | MOV_FROM_REG(39) | ||
777 | MOV_FROM_REG(40) | ||
778 | MOV_FROM_REG(41) | ||
779 | MOV_FROM_REG(42) | ||
780 | MOV_FROM_REG(43) | ||
781 | MOV_FROM_REG(44) | ||
782 | MOV_FROM_REG(45) | ||
783 | MOV_FROM_REG(46) | ||
784 | MOV_FROM_REG(47) | ||
785 | MOV_FROM_REG(48) | ||
786 | MOV_FROM_REG(49) | ||
787 | MOV_FROM_REG(50) | ||
788 | MOV_FROM_REG(51) | ||
789 | MOV_FROM_REG(52) | ||
790 | MOV_FROM_REG(53) | ||
791 | MOV_FROM_REG(54) | ||
792 | MOV_FROM_REG(55) | ||
793 | MOV_FROM_REG(56) | ||
794 | MOV_FROM_REG(57) | ||
795 | MOV_FROM_REG(58) | ||
796 | MOV_FROM_REG(59) | ||
797 | MOV_FROM_REG(60) | ||
798 | MOV_FROM_REG(61) | ||
799 | MOV_FROM_REG(62) | ||
800 | MOV_FROM_REG(63) | ||
801 | MOV_FROM_REG(64) | ||
802 | MOV_FROM_REG(65) | ||
803 | MOV_FROM_REG(66) | ||
804 | MOV_FROM_REG(67) | ||
805 | MOV_FROM_REG(68) | ||
806 | MOV_FROM_REG(69) | ||
807 | MOV_FROM_REG(70) | ||
808 | MOV_FROM_REG(71) | ||
809 | MOV_FROM_REG(72) | ||
810 | MOV_FROM_REG(73) | ||
811 | MOV_FROM_REG(74) | ||
812 | MOV_FROM_REG(75) | ||
813 | MOV_FROM_REG(76) | ||
814 | MOV_FROM_REG(77) | ||
815 | MOV_FROM_REG(78) | ||
816 | MOV_FROM_REG(79) | ||
817 | MOV_FROM_REG(80) | ||
818 | MOV_FROM_REG(81) | ||
819 | MOV_FROM_REG(82) | ||
820 | MOV_FROM_REG(83) | ||
821 | MOV_FROM_REG(84) | ||
822 | MOV_FROM_REG(85) | ||
823 | MOV_FROM_REG(86) | ||
824 | MOV_FROM_REG(87) | ||
825 | MOV_FROM_REG(88) | ||
826 | MOV_FROM_REG(89) | ||
827 | MOV_FROM_REG(90) | ||
828 | MOV_FROM_REG(91) | ||
829 | MOV_FROM_REG(92) | ||
830 | MOV_FROM_REG(93) | ||
831 | MOV_FROM_REG(94) | ||
832 | MOV_FROM_REG(95) | ||
833 | MOV_FROM_REG(96) | ||
834 | MOV_FROM_REG(97) | ||
835 | MOV_FROM_REG(98) | ||
836 | MOV_FROM_REG(99) | ||
837 | MOV_FROM_REG(100) | ||
838 | MOV_FROM_REG(101) | ||
839 | MOV_FROM_REG(102) | ||
840 | MOV_FROM_REG(103) | ||
841 | MOV_FROM_REG(104) | ||
842 | MOV_FROM_REG(105) | ||
843 | MOV_FROM_REG(106) | ||
844 | MOV_FROM_REG(107) | ||
845 | MOV_FROM_REG(108) | ||
846 | MOV_FROM_REG(109) | ||
847 | MOV_FROM_REG(110) | ||
848 | MOV_FROM_REG(111) | ||
849 | MOV_FROM_REG(112) | ||
850 | MOV_FROM_REG(113) | ||
851 | MOV_FROM_REG(114) | ||
852 | MOV_FROM_REG(115) | ||
853 | MOV_FROM_REG(116) | ||
854 | MOV_FROM_REG(117) | ||
855 | MOV_FROM_REG(118) | ||
856 | MOV_FROM_REG(119) | ||
857 | MOV_FROM_REG(120) | ||
858 | MOV_FROM_REG(121) | ||
859 | MOV_FROM_REG(122) | ||
860 | MOV_FROM_REG(123) | ||
861 | MOV_FROM_REG(124) | ||
862 | MOV_FROM_REG(125) | ||
863 | MOV_FROM_REG(126) | ||
864 | MOV_FROM_REG(127) | ||
865 | END(asm_mov_from_reg) | ||
866 | |||
867 | |||
868 | /* must be in bank 0 | ||
869 | * parameter: | ||
870 | * r31: pr | ||
871 | * r24: b0 | ||
872 | */ | ||
873 | ENTRY(kvm_resume_to_guest_with_sync) | ||
874 | adds r19=VMM_VPD_BASE_OFFSET,r21 | ||
875 | mov r16 = r31 | ||
876 | mov r17 = r24 | ||
877 | ;; | ||
878 | {.mii | ||
879 | ld8 r25 =[r19] | ||
880 | nop 0x0 | ||
881 | mov r24 = ip | ||
882 | ;; | ||
883 | } | ||
884 | {.mmb | ||
885 | add r24 =0x20, r24 | ||
886 | nop 0x0 | ||
887 | br.sptk.many kvm_vps_sync_write | ||
888 | } | ||
889 | |||
890 | mov r31 = r16 | ||
891 | mov r24 =r17 | ||
892 | ;; | ||
893 | br.sptk.many kvm_resume_to_guest | ||
894 | END(kvm_resume_to_guest_with_sync) | ||
895 | |||
896 | ENTRY(kvm_resume_to_guest) | ||
897 | adds r16 = VMM_VCPU_SAVED_GP_OFFSET,r21 | ||
898 | ;; | ||
899 | ld8 r1 =[r16] | ||
900 | adds r20 = VMM_VCPU_VSA_BASE_OFFSET,r21 | ||
901 | ;; | ||
902 | mov r16=cr.ipsr | ||
903 | ;; | ||
904 | ld8 r20 = [r20] | ||
905 | adds r19=VMM_VPD_BASE_OFFSET,r21 | ||
906 | ;; | ||
907 | ld8 r25=[r19] | ||
908 | extr.u r17=r16,IA64_PSR_RI_BIT,2 | ||
909 | tbit.nz p6,p7=r16,IA64_PSR_RI_BIT+1 | ||
910 | ;; | ||
911 | (p6) mov r18=cr.iip | ||
912 | (p6) mov r17=r0 | ||
913 | ;; | ||
914 | (p6) add r18=0x10,r18 | ||
915 | (p7) add r17=1,r17 | ||
916 | ;; | ||
917 | (p6) mov cr.iip=r18 | ||
918 | dep r16=r17,r16,IA64_PSR_RI_BIT,2 | ||
919 | ;; | ||
920 | mov cr.ipsr=r16 | ||
921 | adds r19= VPD_VPSR_START_OFFSET,r25 | ||
922 | add r28=PAL_VPS_RESUME_NORMAL,r20 | ||
923 | add r29=PAL_VPS_RESUME_HANDLER,r20 | ||
924 | ;; | ||
925 | ld8 r19=[r19] | ||
926 | mov b0=r29 | ||
927 | mov r27=cr.isr | ||
928 | ;; | ||
929 | tbit.z p6,p7 = r19,IA64_PSR_IC_BIT // p7=vpsr.ic | ||
930 | shr r27=r27,IA64_ISR_IR_BIT | ||
931 | ;; | ||
932 | (p6) ld8 r26=[r25] | ||
933 | (p7) mov b0=r28 | ||
934 | ;; | ||
935 | (p6) dep r26=r27,r26,63,1 | ||
936 | mov pr=r31,-2 | ||
937 | br.sptk.many b0 // call pal service | ||
938 | ;; | ||
939 | END(kvm_resume_to_guest) | ||
940 | |||
941 | |||
942 | MOV_TO_BANK0_REG(16) | ||
943 | MOV_TO_BANK0_REG(17) | ||
944 | MOV_TO_BANK0_REG(18) | ||
945 | MOV_TO_BANK0_REG(19) | ||
946 | MOV_TO_BANK0_REG(20) | ||
947 | MOV_TO_BANK0_REG(21) | ||
948 | MOV_TO_BANK0_REG(22) | ||
949 | MOV_TO_BANK0_REG(23) | ||
950 | MOV_TO_BANK0_REG(24) | ||
951 | MOV_TO_BANK0_REG(25) | ||
952 | MOV_TO_BANK0_REG(26) | ||
953 | MOV_TO_BANK0_REG(27) | ||
954 | MOV_TO_BANK0_REG(28) | ||
955 | MOV_TO_BANK0_REG(29) | ||
956 | MOV_TO_BANK0_REG(30) | ||
957 | MOV_TO_BANK0_REG(31) | ||
958 | |||
959 | |||
960 | // mov to reg table | ||
961 | ENTRY(asm_mov_to_reg) | ||
962 | MOV_TO_REG0 | ||
963 | MOV_TO_REG(1) | ||
964 | MOV_TO_REG(2) | ||
965 | MOV_TO_REG(3) | ||
966 | MOV_TO_REG(4) | ||
967 | MOV_TO_REG(5) | ||
968 | MOV_TO_REG(6) | ||
969 | MOV_TO_REG(7) | ||
970 | MOV_TO_REG(8) | ||
971 | MOV_TO_REG(9) | ||
972 | MOV_TO_REG(10) | ||
973 | MOV_TO_REG(11) | ||
974 | MOV_TO_REG(12) | ||
975 | MOV_TO_REG(13) | ||
976 | MOV_TO_REG(14) | ||
977 | MOV_TO_REG(15) | ||
978 | JMP_TO_MOV_TO_BANK0_REG(16) | ||
979 | JMP_TO_MOV_TO_BANK0_REG(17) | ||
980 | JMP_TO_MOV_TO_BANK0_REG(18) | ||
981 | JMP_TO_MOV_TO_BANK0_REG(19) | ||
982 | JMP_TO_MOV_TO_BANK0_REG(20) | ||
983 | JMP_TO_MOV_TO_BANK0_REG(21) | ||
984 | JMP_TO_MOV_TO_BANK0_REG(22) | ||
985 | JMP_TO_MOV_TO_BANK0_REG(23) | ||
986 | JMP_TO_MOV_TO_BANK0_REG(24) | ||
987 | JMP_TO_MOV_TO_BANK0_REG(25) | ||
988 | JMP_TO_MOV_TO_BANK0_REG(26) | ||
989 | JMP_TO_MOV_TO_BANK0_REG(27) | ||
990 | JMP_TO_MOV_TO_BANK0_REG(28) | ||
991 | JMP_TO_MOV_TO_BANK0_REG(29) | ||
992 | JMP_TO_MOV_TO_BANK0_REG(30) | ||
993 | JMP_TO_MOV_TO_BANK0_REG(31) | ||
994 | MOV_TO_REG(32) | ||
995 | MOV_TO_REG(33) | ||
996 | MOV_TO_REG(34) | ||
997 | MOV_TO_REG(35) | ||
998 | MOV_TO_REG(36) | ||
999 | MOV_TO_REG(37) | ||
1000 | MOV_TO_REG(38) | ||
1001 | MOV_TO_REG(39) | ||
1002 | MOV_TO_REG(40) | ||
1003 | MOV_TO_REG(41) | ||
1004 | MOV_TO_REG(42) | ||
1005 | MOV_TO_REG(43) | ||
1006 | MOV_TO_REG(44) | ||
1007 | MOV_TO_REG(45) | ||
1008 | MOV_TO_REG(46) | ||
1009 | MOV_TO_REG(47) | ||
1010 | MOV_TO_REG(48) | ||
1011 | MOV_TO_REG(49) | ||
1012 | MOV_TO_REG(50) | ||
1013 | MOV_TO_REG(51) | ||
1014 | MOV_TO_REG(52) | ||
1015 | MOV_TO_REG(53) | ||
1016 | MOV_TO_REG(54) | ||
1017 | MOV_TO_REG(55) | ||
1018 | MOV_TO_REG(56) | ||
1019 | MOV_TO_REG(57) | ||
1020 | MOV_TO_REG(58) | ||
1021 | MOV_TO_REG(59) | ||
1022 | MOV_TO_REG(60) | ||
1023 | MOV_TO_REG(61) | ||
1024 | MOV_TO_REG(62) | ||
1025 | MOV_TO_REG(63) | ||
1026 | MOV_TO_REG(64) | ||
1027 | MOV_TO_REG(65) | ||
1028 | MOV_TO_REG(66) | ||
1029 | MOV_TO_REG(67) | ||
1030 | MOV_TO_REG(68) | ||
1031 | MOV_TO_REG(69) | ||
1032 | MOV_TO_REG(70) | ||
1033 | MOV_TO_REG(71) | ||
1034 | MOV_TO_REG(72) | ||
1035 | MOV_TO_REG(73) | ||
1036 | MOV_TO_REG(74) | ||
1037 | MOV_TO_REG(75) | ||
1038 | MOV_TO_REG(76) | ||
1039 | MOV_TO_REG(77) | ||
1040 | MOV_TO_REG(78) | ||
1041 | MOV_TO_REG(79) | ||
1042 | MOV_TO_REG(80) | ||
1043 | MOV_TO_REG(81) | ||
1044 | MOV_TO_REG(82) | ||
1045 | MOV_TO_REG(83) | ||
1046 | MOV_TO_REG(84) | ||
1047 | MOV_TO_REG(85) | ||
1048 | MOV_TO_REG(86) | ||
1049 | MOV_TO_REG(87) | ||
1050 | MOV_TO_REG(88) | ||
1051 | MOV_TO_REG(89) | ||
1052 | MOV_TO_REG(90) | ||
1053 | MOV_TO_REG(91) | ||
1054 | MOV_TO_REG(92) | ||
1055 | MOV_TO_REG(93) | ||
1056 | MOV_TO_REG(94) | ||
1057 | MOV_TO_REG(95) | ||
1058 | MOV_TO_REG(96) | ||
1059 | MOV_TO_REG(97) | ||
1060 | MOV_TO_REG(98) | ||
1061 | MOV_TO_REG(99) | ||
1062 | MOV_TO_REG(100) | ||
1063 | MOV_TO_REG(101) | ||
1064 | MOV_TO_REG(102) | ||
1065 | MOV_TO_REG(103) | ||
1066 | MOV_TO_REG(104) | ||
1067 | MOV_TO_REG(105) | ||
1068 | MOV_TO_REG(106) | ||
1069 | MOV_TO_REG(107) | ||
1070 | MOV_TO_REG(108) | ||
1071 | MOV_TO_REG(109) | ||
1072 | MOV_TO_REG(110) | ||
1073 | MOV_TO_REG(111) | ||
1074 | MOV_TO_REG(112) | ||
1075 | MOV_TO_REG(113) | ||
1076 | MOV_TO_REG(114) | ||
1077 | MOV_TO_REG(115) | ||
1078 | MOV_TO_REG(116) | ||
1079 | MOV_TO_REG(117) | ||
1080 | MOV_TO_REG(118) | ||
1081 | MOV_TO_REG(119) | ||
1082 | MOV_TO_REG(120) | ||
1083 | MOV_TO_REG(121) | ||
1084 | MOV_TO_REG(122) | ||
1085 | MOV_TO_REG(123) | ||
1086 | MOV_TO_REG(124) | ||
1087 | MOV_TO_REG(125) | ||
1088 | MOV_TO_REG(126) | ||
1089 | MOV_TO_REG(127) | ||
1090 | END(asm_mov_to_reg) | ||
diff --git a/arch/ia64/kvm/process.c b/arch/ia64/kvm/process.c deleted file mode 100644 index b0398740b48d..000000000000 --- a/arch/ia64/kvm/process.c +++ /dev/null | |||
@@ -1,1024 +0,0 @@ | |||
1 | /* | ||
2 | * process.c: handle interruption inject for guests. | ||
3 | * Copyright (c) 2005, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | ||
16 | * Place - Suite 330, Boston, MA 02111-1307 USA. | ||
17 | * | ||
18 | * Shaofan Li (Susue Li) <susie.li@intel.com> | ||
19 | * Xiaoyan Feng (Fleming Feng) <fleming.feng@intel.com> | ||
20 | * Xuefei Xu (Anthony Xu) (Anthony.xu@intel.com) | ||
21 | * Xiantao Zhang (xiantao.zhang@intel.com) | ||
22 | */ | ||
23 | #include "vcpu.h" | ||
24 | |||
25 | #include <asm/pal.h> | ||
26 | #include <asm/sal.h> | ||
27 | #include <asm/fpswa.h> | ||
28 | #include <asm/kregs.h> | ||
29 | #include <asm/tlb.h> | ||
30 | |||
31 | fpswa_interface_t *vmm_fpswa_interface; | ||
32 | |||
33 | #define IA64_VHPT_TRANS_VECTOR 0x0000 | ||
34 | #define IA64_INST_TLB_VECTOR 0x0400 | ||
35 | #define IA64_DATA_TLB_VECTOR 0x0800 | ||
36 | #define IA64_ALT_INST_TLB_VECTOR 0x0c00 | ||
37 | #define IA64_ALT_DATA_TLB_VECTOR 0x1000 | ||
38 | #define IA64_DATA_NESTED_TLB_VECTOR 0x1400 | ||
39 | #define IA64_INST_KEY_MISS_VECTOR 0x1800 | ||
40 | #define IA64_DATA_KEY_MISS_VECTOR 0x1c00 | ||
41 | #define IA64_DIRTY_BIT_VECTOR 0x2000 | ||
42 | #define IA64_INST_ACCESS_BIT_VECTOR 0x2400 | ||
43 | #define IA64_DATA_ACCESS_BIT_VECTOR 0x2800 | ||
44 | #define IA64_BREAK_VECTOR 0x2c00 | ||
45 | #define IA64_EXTINT_VECTOR 0x3000 | ||
46 | #define IA64_PAGE_NOT_PRESENT_VECTOR 0x5000 | ||
47 | #define IA64_KEY_PERMISSION_VECTOR 0x5100 | ||
48 | #define IA64_INST_ACCESS_RIGHTS_VECTOR 0x5200 | ||
49 | #define IA64_DATA_ACCESS_RIGHTS_VECTOR 0x5300 | ||
50 | #define IA64_GENEX_VECTOR 0x5400 | ||
51 | #define IA64_DISABLED_FPREG_VECTOR 0x5500 | ||
52 | #define IA64_NAT_CONSUMPTION_VECTOR 0x5600 | ||
53 | #define IA64_SPECULATION_VECTOR 0x5700 /* UNUSED */ | ||
54 | #define IA64_DEBUG_VECTOR 0x5900 | ||
55 | #define IA64_UNALIGNED_REF_VECTOR 0x5a00 | ||
56 | #define IA64_UNSUPPORTED_DATA_REF_VECTOR 0x5b00 | ||
57 | #define IA64_FP_FAULT_VECTOR 0x5c00 | ||
58 | #define IA64_FP_TRAP_VECTOR 0x5d00 | ||
59 | #define IA64_LOWERPRIV_TRANSFER_TRAP_VECTOR 0x5e00 | ||
60 | #define IA64_TAKEN_BRANCH_TRAP_VECTOR 0x5f00 | ||
61 | #define IA64_SINGLE_STEP_TRAP_VECTOR 0x6000 | ||
62 | |||
63 | /* SDM vol2 5.5 - IVA based interruption handling */ | ||
64 | #define INITIAL_PSR_VALUE_AT_INTERRUPTION (IA64_PSR_UP | IA64_PSR_MFL |\ | ||
65 | IA64_PSR_MFH | IA64_PSR_PK | IA64_PSR_DT | \ | ||
66 | IA64_PSR_RT | IA64_PSR_MC|IA64_PSR_IT) | ||
67 | |||
68 | #define DOMN_PAL_REQUEST 0x110000 | ||
69 | #define DOMN_SAL_REQUEST 0x110001 | ||
70 | |||
71 | static u64 vec2off[68] = {0x0, 0x400, 0x800, 0xc00, 0x1000, 0x1400, 0x1800, | ||
72 | 0x1c00, 0x2000, 0x2400, 0x2800, 0x2c00, 0x3000, 0x3400, 0x3800, 0x3c00, | ||
73 | 0x4000, 0x4400, 0x4800, 0x4c00, 0x5000, 0x5100, 0x5200, 0x5300, 0x5400, | ||
74 | 0x5500, 0x5600, 0x5700, 0x5800, 0x5900, 0x5a00, 0x5b00, 0x5c00, 0x5d00, | ||
75 | 0x5e00, 0x5f00, 0x6000, 0x6100, 0x6200, 0x6300, 0x6400, 0x6500, 0x6600, | ||
76 | 0x6700, 0x6800, 0x6900, 0x6a00, 0x6b00, 0x6c00, 0x6d00, 0x6e00, 0x6f00, | ||
77 | 0x7000, 0x7100, 0x7200, 0x7300, 0x7400, 0x7500, 0x7600, 0x7700, 0x7800, | ||
78 | 0x7900, 0x7a00, 0x7b00, 0x7c00, 0x7d00, 0x7e00, 0x7f00 | ||
79 | }; | ||
80 | |||
81 | static void collect_interruption(struct kvm_vcpu *vcpu) | ||
82 | { | ||
83 | u64 ipsr; | ||
84 | u64 vdcr; | ||
85 | u64 vifs; | ||
86 | unsigned long vpsr; | ||
87 | struct kvm_pt_regs *regs = vcpu_regs(vcpu); | ||
88 | |||
89 | vpsr = vcpu_get_psr(vcpu); | ||
90 | vcpu_bsw0(vcpu); | ||
91 | if (vpsr & IA64_PSR_IC) { | ||
92 | |||
93 | /* Sync mpsr id/da/dd/ss/ed bits to vipsr | ||
94 | * since after guest do rfi, we still want these bits on in | ||
95 | * mpsr | ||
96 | */ | ||
97 | |||
98 | ipsr = regs->cr_ipsr; | ||
99 | vpsr = vpsr | (ipsr & (IA64_PSR_ID | IA64_PSR_DA | ||
100 | | IA64_PSR_DD | IA64_PSR_SS | ||
101 | | IA64_PSR_ED)); | ||
102 | vcpu_set_ipsr(vcpu, vpsr); | ||
103 | |||
104 | /* Currently, for trap, we do not advance IIP to next | ||
105 | * instruction. That's because we assume caller already | ||
106 | * set up IIP correctly | ||
107 | */ | ||
108 | |||
109 | vcpu_set_iip(vcpu , regs->cr_iip); | ||
110 | |||
111 | /* set vifs.v to zero */ | ||
112 | vifs = VCPU(vcpu, ifs); | ||
113 | vifs &= ~IA64_IFS_V; | ||
114 | vcpu_set_ifs(vcpu, vifs); | ||
115 | |||
116 | vcpu_set_iipa(vcpu, VMX(vcpu, cr_iipa)); | ||
117 | } | ||
118 | |||
119 | vdcr = VCPU(vcpu, dcr); | ||
120 | |||
121 | /* Set guest psr | ||
122 | * up/mfl/mfh/pk/dt/rt/mc/it keeps unchanged | ||
123 | * be: set to the value of dcr.be | ||
124 | * pp: set to the value of dcr.pp | ||
125 | */ | ||
126 | vpsr &= INITIAL_PSR_VALUE_AT_INTERRUPTION; | ||
127 | vpsr |= (vdcr & IA64_DCR_BE); | ||
128 | |||
129 | /* VDCR pp bit position is different from VPSR pp bit */ | ||
130 | if (vdcr & IA64_DCR_PP) { | ||
131 | vpsr |= IA64_PSR_PP; | ||
132 | } else { | ||
133 | vpsr &= ~IA64_PSR_PP; | ||
134 | } | ||
135 | |||
136 | vcpu_set_psr(vcpu, vpsr); | ||
137 | |||
138 | } | ||
139 | |||
140 | void inject_guest_interruption(struct kvm_vcpu *vcpu, u64 vec) | ||
141 | { | ||
142 | u64 viva; | ||
143 | struct kvm_pt_regs *regs; | ||
144 | union ia64_isr pt_isr; | ||
145 | |||
146 | regs = vcpu_regs(vcpu); | ||
147 | |||
148 | /* clear cr.isr.ir (incomplete register frame)*/ | ||
149 | pt_isr.val = VMX(vcpu, cr_isr); | ||
150 | pt_isr.ir = 0; | ||
151 | VMX(vcpu, cr_isr) = pt_isr.val; | ||
152 | |||
153 | collect_interruption(vcpu); | ||
154 | |||
155 | viva = vcpu_get_iva(vcpu); | ||
156 | regs->cr_iip = viva + vec; | ||
157 | } | ||
158 | |||
159 | static u64 vcpu_get_itir_on_fault(struct kvm_vcpu *vcpu, u64 ifa) | ||
160 | { | ||
161 | union ia64_rr rr, rr1; | ||
162 | |||
163 | rr.val = vcpu_get_rr(vcpu, ifa); | ||
164 | rr1.val = 0; | ||
165 | rr1.ps = rr.ps; | ||
166 | rr1.rid = rr.rid; | ||
167 | return (rr1.val); | ||
168 | } | ||
169 | |||
170 | /* | ||
171 | * Set vIFA & vITIR & vIHA, when vPSR.ic =1 | ||
172 | * Parameter: | ||
173 | * set_ifa: if true, set vIFA | ||
174 | * set_itir: if true, set vITIR | ||
175 | * set_iha: if true, set vIHA | ||
176 | */ | ||
177 | void set_ifa_itir_iha(struct kvm_vcpu *vcpu, u64 vadr, | ||
178 | int set_ifa, int set_itir, int set_iha) | ||
179 | { | ||
180 | long vpsr; | ||
181 | u64 value; | ||
182 | |||
183 | vpsr = VCPU(vcpu, vpsr); | ||
184 | /* Vol2, Table 8-1 */ | ||
185 | if (vpsr & IA64_PSR_IC) { | ||
186 | if (set_ifa) | ||
187 | vcpu_set_ifa(vcpu, vadr); | ||
188 | if (set_itir) { | ||
189 | value = vcpu_get_itir_on_fault(vcpu, vadr); | ||
190 | vcpu_set_itir(vcpu, value); | ||
191 | } | ||
192 | |||
193 | if (set_iha) { | ||
194 | value = vcpu_thash(vcpu, vadr); | ||
195 | vcpu_set_iha(vcpu, value); | ||
196 | } | ||
197 | } | ||
198 | } | ||
199 | |||
200 | /* | ||
201 | * Data TLB Fault | ||
202 | * @ Data TLB vector | ||
203 | * Refer to SDM Vol2 Table 5-6 & 8-1 | ||
204 | */ | ||
205 | void dtlb_fault(struct kvm_vcpu *vcpu, u64 vadr) | ||
206 | { | ||
207 | /* If vPSR.ic, IFA, ITIR, IHA */ | ||
208 | set_ifa_itir_iha(vcpu, vadr, 1, 1, 1); | ||
209 | inject_guest_interruption(vcpu, IA64_DATA_TLB_VECTOR); | ||
210 | } | ||
211 | |||
212 | /* | ||
213 | * Instruction TLB Fault | ||
214 | * @ Instruction TLB vector | ||
215 | * Refer to SDM Vol2 Table 5-6 & 8-1 | ||
216 | */ | ||
217 | void itlb_fault(struct kvm_vcpu *vcpu, u64 vadr) | ||
218 | { | ||
219 | /* If vPSR.ic, IFA, ITIR, IHA */ | ||
220 | set_ifa_itir_iha(vcpu, vadr, 1, 1, 1); | ||
221 | inject_guest_interruption(vcpu, IA64_INST_TLB_VECTOR); | ||
222 | } | ||
223 | |||
224 | /* | ||
225 | * Data Nested TLB Fault | ||
226 | * @ Data Nested TLB Vector | ||
227 | * Refer to SDM Vol2 Table 5-6 & 8-1 | ||
228 | */ | ||
229 | void nested_dtlb(struct kvm_vcpu *vcpu) | ||
230 | { | ||
231 | inject_guest_interruption(vcpu, IA64_DATA_NESTED_TLB_VECTOR); | ||
232 | } | ||
233 | |||
234 | /* | ||
235 | * Alternate Data TLB Fault | ||
236 | * @ Alternate Data TLB vector | ||
237 | * Refer to SDM Vol2 Table 5-6 & 8-1 | ||
238 | */ | ||
239 | void alt_dtlb(struct kvm_vcpu *vcpu, u64 vadr) | ||
240 | { | ||
241 | set_ifa_itir_iha(vcpu, vadr, 1, 1, 0); | ||
242 | inject_guest_interruption(vcpu, IA64_ALT_DATA_TLB_VECTOR); | ||
243 | } | ||
244 | |||
245 | /* | ||
246 | * Data TLB Fault | ||
247 | * @ Data TLB vector | ||
248 | * Refer to SDM Vol2 Table 5-6 & 8-1 | ||
249 | */ | ||
250 | void alt_itlb(struct kvm_vcpu *vcpu, u64 vadr) | ||
251 | { | ||
252 | set_ifa_itir_iha(vcpu, vadr, 1, 1, 0); | ||
253 | inject_guest_interruption(vcpu, IA64_ALT_INST_TLB_VECTOR); | ||
254 | } | ||
255 | |||
256 | /* Deal with: | ||
257 | * VHPT Translation Vector | ||
258 | */ | ||
259 | static void _vhpt_fault(struct kvm_vcpu *vcpu, u64 vadr) | ||
260 | { | ||
261 | /* If vPSR.ic, IFA, ITIR, IHA*/ | ||
262 | set_ifa_itir_iha(vcpu, vadr, 1, 1, 1); | ||
263 | inject_guest_interruption(vcpu, IA64_VHPT_TRANS_VECTOR); | ||
264 | } | ||
265 | |||
266 | /* | ||
267 | * VHPT Instruction Fault | ||
268 | * @ VHPT Translation vector | ||
269 | * Refer to SDM Vol2 Table 5-6 & 8-1 | ||
270 | */ | ||
271 | void ivhpt_fault(struct kvm_vcpu *vcpu, u64 vadr) | ||
272 | { | ||
273 | _vhpt_fault(vcpu, vadr); | ||
274 | } | ||
275 | |||
276 | /* | ||
277 | * VHPT Data Fault | ||
278 | * @ VHPT Translation vector | ||
279 | * Refer to SDM Vol2 Table 5-6 & 8-1 | ||
280 | */ | ||
281 | void dvhpt_fault(struct kvm_vcpu *vcpu, u64 vadr) | ||
282 | { | ||
283 | _vhpt_fault(vcpu, vadr); | ||
284 | } | ||
285 | |||
286 | /* | ||
287 | * Deal with: | ||
288 | * General Exception vector | ||
289 | */ | ||
290 | void _general_exception(struct kvm_vcpu *vcpu) | ||
291 | { | ||
292 | inject_guest_interruption(vcpu, IA64_GENEX_VECTOR); | ||
293 | } | ||
294 | |||
295 | /* | ||
296 | * Illegal Operation Fault | ||
297 | * @ General Exception Vector | ||
298 | * Refer to SDM Vol2 Table 5-6 & 8-1 | ||
299 | */ | ||
300 | void illegal_op(struct kvm_vcpu *vcpu) | ||
301 | { | ||
302 | _general_exception(vcpu); | ||
303 | } | ||
304 | |||
305 | /* | ||
306 | * Illegal Dependency Fault | ||
307 | * @ General Exception Vector | ||
308 | * Refer to SDM Vol2 Table 5-6 & 8-1 | ||
309 | */ | ||
310 | void illegal_dep(struct kvm_vcpu *vcpu) | ||
311 | { | ||
312 | _general_exception(vcpu); | ||
313 | } | ||
314 | |||
315 | /* | ||
316 | * Reserved Register/Field Fault | ||
317 | * @ General Exception Vector | ||
318 | * Refer to SDM Vol2 Table 5-6 & 8-1 | ||
319 | */ | ||
320 | void rsv_reg_field(struct kvm_vcpu *vcpu) | ||
321 | { | ||
322 | _general_exception(vcpu); | ||
323 | } | ||
324 | /* | ||
325 | * Privileged Operation Fault | ||
326 | * @ General Exception Vector | ||
327 | * Refer to SDM Vol2 Table 5-6 & 8-1 | ||
328 | */ | ||
329 | |||
330 | void privilege_op(struct kvm_vcpu *vcpu) | ||
331 | { | ||
332 | _general_exception(vcpu); | ||
333 | } | ||
334 | |||
335 | /* | ||
336 | * Unimplement Data Address Fault | ||
337 | * @ General Exception Vector | ||
338 | * Refer to SDM Vol2 Table 5-6 & 8-1 | ||
339 | */ | ||
340 | void unimpl_daddr(struct kvm_vcpu *vcpu) | ||
341 | { | ||
342 | _general_exception(vcpu); | ||
343 | } | ||
344 | |||
345 | /* | ||
346 | * Privileged Register Fault | ||
347 | * @ General Exception Vector | ||
348 | * Refer to SDM Vol2 Table 5-6 & 8-1 | ||
349 | */ | ||
350 | void privilege_reg(struct kvm_vcpu *vcpu) | ||
351 | { | ||
352 | _general_exception(vcpu); | ||
353 | } | ||
354 | |||
355 | /* Deal with | ||
356 | * Nat consumption vector | ||
357 | * Parameter: | ||
358 | * vaddr: Optional, if t == REGISTER | ||
359 | */ | ||
360 | static void _nat_consumption_fault(struct kvm_vcpu *vcpu, u64 vadr, | ||
361 | enum tlb_miss_type t) | ||
362 | { | ||
363 | /* If vPSR.ic && t == DATA/INST, IFA */ | ||
364 | if (t == DATA || t == INSTRUCTION) { | ||
365 | /* IFA */ | ||
366 | set_ifa_itir_iha(vcpu, vadr, 1, 0, 0); | ||
367 | } | ||
368 | |||
369 | inject_guest_interruption(vcpu, IA64_NAT_CONSUMPTION_VECTOR); | ||
370 | } | ||
371 | |||
372 | /* | ||
373 | * Instruction Nat Page Consumption Fault | ||
374 | * @ Nat Consumption Vector | ||
375 | * Refer to SDM Vol2 Table 5-6 & 8-1 | ||
376 | */ | ||
377 | void inat_page_consumption(struct kvm_vcpu *vcpu, u64 vadr) | ||
378 | { | ||
379 | _nat_consumption_fault(vcpu, vadr, INSTRUCTION); | ||
380 | } | ||
381 | |||
382 | /* | ||
383 | * Register Nat Consumption Fault | ||
384 | * @ Nat Consumption Vector | ||
385 | * Refer to SDM Vol2 Table 5-6 & 8-1 | ||
386 | */ | ||
387 | void rnat_consumption(struct kvm_vcpu *vcpu) | ||
388 | { | ||
389 | _nat_consumption_fault(vcpu, 0, REGISTER); | ||
390 | } | ||
391 | |||
392 | /* | ||
393 | * Data Nat Page Consumption Fault | ||
394 | * @ Nat Consumption Vector | ||
395 | * Refer to SDM Vol2 Table 5-6 & 8-1 | ||
396 | */ | ||
397 | void dnat_page_consumption(struct kvm_vcpu *vcpu, u64 vadr) | ||
398 | { | ||
399 | _nat_consumption_fault(vcpu, vadr, DATA); | ||
400 | } | ||
401 | |||
402 | /* Deal with | ||
403 | * Page not present vector | ||
404 | */ | ||
405 | static void __page_not_present(struct kvm_vcpu *vcpu, u64 vadr) | ||
406 | { | ||
407 | /* If vPSR.ic, IFA, ITIR */ | ||
408 | set_ifa_itir_iha(vcpu, vadr, 1, 1, 0); | ||
409 | inject_guest_interruption(vcpu, IA64_PAGE_NOT_PRESENT_VECTOR); | ||
410 | } | ||
411 | |||
412 | void data_page_not_present(struct kvm_vcpu *vcpu, u64 vadr) | ||
413 | { | ||
414 | __page_not_present(vcpu, vadr); | ||
415 | } | ||
416 | |||
417 | void inst_page_not_present(struct kvm_vcpu *vcpu, u64 vadr) | ||
418 | { | ||
419 | __page_not_present(vcpu, vadr); | ||
420 | } | ||
421 | |||
422 | /* Deal with | ||
423 | * Data access rights vector | ||
424 | */ | ||
425 | void data_access_rights(struct kvm_vcpu *vcpu, u64 vadr) | ||
426 | { | ||
427 | /* If vPSR.ic, IFA, ITIR */ | ||
428 | set_ifa_itir_iha(vcpu, vadr, 1, 1, 0); | ||
429 | inject_guest_interruption(vcpu, IA64_DATA_ACCESS_RIGHTS_VECTOR); | ||
430 | } | ||
431 | |||
432 | fpswa_ret_t vmm_fp_emulate(int fp_fault, void *bundle, unsigned long *ipsr, | ||
433 | unsigned long *fpsr, unsigned long *isr, unsigned long *pr, | ||
434 | unsigned long *ifs, struct kvm_pt_regs *regs) | ||
435 | { | ||
436 | fp_state_t fp_state; | ||
437 | fpswa_ret_t ret; | ||
438 | struct kvm_vcpu *vcpu = current_vcpu; | ||
439 | |||
440 | uint64_t old_rr7 = ia64_get_rr(7UL<<61); | ||
441 | |||
442 | if (!vmm_fpswa_interface) | ||
443 | return (fpswa_ret_t) {-1, 0, 0, 0}; | ||
444 | |||
445 | memset(&fp_state, 0, sizeof(fp_state_t)); | ||
446 | |||
447 | /* | ||
448 | * compute fp_state. only FP registers f6 - f11 are used by the | ||
449 | * vmm, so set those bits in the mask and set the low volatile | ||
450 | * pointer to point to these registers. | ||
451 | */ | ||
452 | fp_state.bitmask_low64 = 0xfc0; /* bit6..bit11 */ | ||
453 | |||
454 | fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) ®s->f6; | ||
455 | |||
456 | /* | ||
457 | * unsigned long (*EFI_FPSWA) ( | ||
458 | * unsigned long trap_type, | ||
459 | * void *Bundle, | ||
460 | * unsigned long *pipsr, | ||
461 | * unsigned long *pfsr, | ||
462 | * unsigned long *pisr, | ||
463 | * unsigned long *ppreds, | ||
464 | * unsigned long *pifs, | ||
465 | * void *fp_state); | ||
466 | */ | ||
467 | /*Call host fpswa interface directly to virtualize | ||
468 | *guest fpswa request! | ||
469 | */ | ||
470 | ia64_set_rr(7UL << 61, vcpu->arch.host.rr[7]); | ||
471 | ia64_srlz_d(); | ||
472 | |||
473 | ret = (*vmm_fpswa_interface->fpswa) (fp_fault, bundle, | ||
474 | ipsr, fpsr, isr, pr, ifs, &fp_state); | ||
475 | ia64_set_rr(7UL << 61, old_rr7); | ||
476 | ia64_srlz_d(); | ||
477 | return ret; | ||
478 | } | ||
479 | |||
480 | /* | ||
481 | * Handle floating-point assist faults and traps for domain. | ||
482 | */ | ||
483 | unsigned long vmm_handle_fpu_swa(int fp_fault, struct kvm_pt_regs *regs, | ||
484 | unsigned long isr) | ||
485 | { | ||
486 | struct kvm_vcpu *v = current_vcpu; | ||
487 | IA64_BUNDLE bundle; | ||
488 | unsigned long fault_ip; | ||
489 | fpswa_ret_t ret; | ||
490 | |||
491 | fault_ip = regs->cr_iip; | ||
492 | /* | ||
493 | * When the FP trap occurs, the trapping instruction is completed. | ||
494 | * If ipsr.ri == 0, there is the trapping instruction in previous | ||
495 | * bundle. | ||
496 | */ | ||
497 | if (!fp_fault && (ia64_psr(regs)->ri == 0)) | ||
498 | fault_ip -= 16; | ||
499 | |||
500 | if (fetch_code(v, fault_ip, &bundle)) | ||
501 | return -EAGAIN; | ||
502 | |||
503 | if (!bundle.i64[0] && !bundle.i64[1]) | ||
504 | return -EACCES; | ||
505 | |||
506 | ret = vmm_fp_emulate(fp_fault, &bundle, ®s->cr_ipsr, ®s->ar_fpsr, | ||
507 | &isr, ®s->pr, ®s->cr_ifs, regs); | ||
508 | return ret.status; | ||
509 | } | ||
510 | |||
511 | void reflect_interruption(u64 ifa, u64 isr, u64 iim, | ||
512 | u64 vec, struct kvm_pt_regs *regs) | ||
513 | { | ||
514 | u64 vector; | ||
515 | int status ; | ||
516 | struct kvm_vcpu *vcpu = current_vcpu; | ||
517 | u64 vpsr = VCPU(vcpu, vpsr); | ||
518 | |||
519 | vector = vec2off[vec]; | ||
520 | |||
521 | if (!(vpsr & IA64_PSR_IC) && (vector != IA64_DATA_NESTED_TLB_VECTOR)) { | ||
522 | panic_vm(vcpu, "Interruption with vector :0x%lx occurs " | ||
523 | "with psr.ic = 0\n", vector); | ||
524 | return; | ||
525 | } | ||
526 | |||
527 | switch (vec) { | ||
528 | case 32: /*IA64_FP_FAULT_VECTOR*/ | ||
529 | status = vmm_handle_fpu_swa(1, regs, isr); | ||
530 | if (!status) { | ||
531 | vcpu_increment_iip(vcpu); | ||
532 | return; | ||
533 | } else if (-EAGAIN == status) | ||
534 | return; | ||
535 | break; | ||
536 | case 33: /*IA64_FP_TRAP_VECTOR*/ | ||
537 | status = vmm_handle_fpu_swa(0, regs, isr); | ||
538 | if (!status) | ||
539 | return ; | ||
540 | break; | ||
541 | } | ||
542 | |||
543 | VCPU(vcpu, isr) = isr; | ||
544 | VCPU(vcpu, iipa) = regs->cr_iip; | ||
545 | if (vector == IA64_BREAK_VECTOR || vector == IA64_SPECULATION_VECTOR) | ||
546 | VCPU(vcpu, iim) = iim; | ||
547 | else | ||
548 | set_ifa_itir_iha(vcpu, ifa, 1, 1, 1); | ||
549 | |||
550 | inject_guest_interruption(vcpu, vector); | ||
551 | } | ||
552 | |||
553 | static unsigned long kvm_trans_pal_call_args(struct kvm_vcpu *vcpu, | ||
554 | unsigned long arg) | ||
555 | { | ||
556 | struct thash_data *data; | ||
557 | unsigned long gpa, poff; | ||
558 | |||
559 | if (!is_physical_mode(vcpu)) { | ||
560 | /* Depends on caller to provide the DTR or DTC mapping.*/ | ||
561 | data = vtlb_lookup(vcpu, arg, D_TLB); | ||
562 | if (data) | ||
563 | gpa = data->page_flags & _PAGE_PPN_MASK; | ||
564 | else { | ||
565 | data = vhpt_lookup(arg); | ||
566 | if (!data) | ||
567 | return 0; | ||
568 | gpa = data->gpaddr & _PAGE_PPN_MASK; | ||
569 | } | ||
570 | |||
571 | poff = arg & (PSIZE(data->ps) - 1); | ||
572 | arg = PAGEALIGN(gpa, data->ps) | poff; | ||
573 | } | ||
574 | arg = kvm_gpa_to_mpa(arg << 1 >> 1); | ||
575 | |||
576 | return (unsigned long)__va(arg); | ||
577 | } | ||
578 | |||
579 | static void set_pal_call_data(struct kvm_vcpu *vcpu) | ||
580 | { | ||
581 | struct exit_ctl_data *p = &vcpu->arch.exit_data; | ||
582 | unsigned long gr28 = vcpu_get_gr(vcpu, 28); | ||
583 | unsigned long gr29 = vcpu_get_gr(vcpu, 29); | ||
584 | unsigned long gr30 = vcpu_get_gr(vcpu, 30); | ||
585 | |||
586 | /*FIXME:For static and stacked convention, firmware | ||
587 | * has put the parameters in gr28-gr31 before | ||
588 | * break to vmm !!*/ | ||
589 | |||
590 | switch (gr28) { | ||
591 | case PAL_PERF_MON_INFO: | ||
592 | case PAL_HALT_INFO: | ||
593 | p->u.pal_data.gr29 = kvm_trans_pal_call_args(vcpu, gr29); | ||
594 | p->u.pal_data.gr30 = vcpu_get_gr(vcpu, 30); | ||
595 | break; | ||
596 | case PAL_BRAND_INFO: | ||
597 | p->u.pal_data.gr29 = gr29; | ||
598 | p->u.pal_data.gr30 = kvm_trans_pal_call_args(vcpu, gr30); | ||
599 | break; | ||
600 | default: | ||
601 | p->u.pal_data.gr29 = gr29; | ||
602 | p->u.pal_data.gr30 = vcpu_get_gr(vcpu, 30); | ||
603 | } | ||
604 | p->u.pal_data.gr28 = gr28; | ||
605 | p->u.pal_data.gr31 = vcpu_get_gr(vcpu, 31); | ||
606 | |||
607 | p->exit_reason = EXIT_REASON_PAL_CALL; | ||
608 | } | ||
609 | |||
610 | static void get_pal_call_result(struct kvm_vcpu *vcpu) | ||
611 | { | ||
612 | struct exit_ctl_data *p = &vcpu->arch.exit_data; | ||
613 | |||
614 | if (p->exit_reason == EXIT_REASON_PAL_CALL) { | ||
615 | vcpu_set_gr(vcpu, 8, p->u.pal_data.ret.status, 0); | ||
616 | vcpu_set_gr(vcpu, 9, p->u.pal_data.ret.v0, 0); | ||
617 | vcpu_set_gr(vcpu, 10, p->u.pal_data.ret.v1, 0); | ||
618 | vcpu_set_gr(vcpu, 11, p->u.pal_data.ret.v2, 0); | ||
619 | } else | ||
620 | panic_vm(vcpu, "Mis-set for exit reason!\n"); | ||
621 | } | ||
622 | |||
623 | static void set_sal_call_data(struct kvm_vcpu *vcpu) | ||
624 | { | ||
625 | struct exit_ctl_data *p = &vcpu->arch.exit_data; | ||
626 | |||
627 | p->u.sal_data.in0 = vcpu_get_gr(vcpu, 32); | ||
628 | p->u.sal_data.in1 = vcpu_get_gr(vcpu, 33); | ||
629 | p->u.sal_data.in2 = vcpu_get_gr(vcpu, 34); | ||
630 | p->u.sal_data.in3 = vcpu_get_gr(vcpu, 35); | ||
631 | p->u.sal_data.in4 = vcpu_get_gr(vcpu, 36); | ||
632 | p->u.sal_data.in5 = vcpu_get_gr(vcpu, 37); | ||
633 | p->u.sal_data.in6 = vcpu_get_gr(vcpu, 38); | ||
634 | p->u.sal_data.in7 = vcpu_get_gr(vcpu, 39); | ||
635 | p->exit_reason = EXIT_REASON_SAL_CALL; | ||
636 | } | ||
637 | |||
638 | static void get_sal_call_result(struct kvm_vcpu *vcpu) | ||
639 | { | ||
640 | struct exit_ctl_data *p = &vcpu->arch.exit_data; | ||
641 | |||
642 | if (p->exit_reason == EXIT_REASON_SAL_CALL) { | ||
643 | vcpu_set_gr(vcpu, 8, p->u.sal_data.ret.r8, 0); | ||
644 | vcpu_set_gr(vcpu, 9, p->u.sal_data.ret.r9, 0); | ||
645 | vcpu_set_gr(vcpu, 10, p->u.sal_data.ret.r10, 0); | ||
646 | vcpu_set_gr(vcpu, 11, p->u.sal_data.ret.r11, 0); | ||
647 | } else | ||
648 | panic_vm(vcpu, "Mis-set for exit reason!\n"); | ||
649 | } | ||
650 | |||
651 | void kvm_ia64_handle_break(unsigned long ifa, struct kvm_pt_regs *regs, | ||
652 | unsigned long isr, unsigned long iim) | ||
653 | { | ||
654 | struct kvm_vcpu *v = current_vcpu; | ||
655 | long psr; | ||
656 | |||
657 | if (ia64_psr(regs)->cpl == 0) { | ||
658 | /* Allow hypercalls only when cpl = 0. */ | ||
659 | if (iim == DOMN_PAL_REQUEST) { | ||
660 | local_irq_save(psr); | ||
661 | set_pal_call_data(v); | ||
662 | vmm_transition(v); | ||
663 | get_pal_call_result(v); | ||
664 | vcpu_increment_iip(v); | ||
665 | local_irq_restore(psr); | ||
666 | return; | ||
667 | } else if (iim == DOMN_SAL_REQUEST) { | ||
668 | local_irq_save(psr); | ||
669 | set_sal_call_data(v); | ||
670 | vmm_transition(v); | ||
671 | get_sal_call_result(v); | ||
672 | vcpu_increment_iip(v); | ||
673 | local_irq_restore(psr); | ||
674 | return; | ||
675 | } | ||
676 | } | ||
677 | reflect_interruption(ifa, isr, iim, 11, regs); | ||
678 | } | ||
679 | |||
680 | void check_pending_irq(struct kvm_vcpu *vcpu) | ||
681 | { | ||
682 | int mask, h_pending, h_inservice; | ||
683 | u64 isr; | ||
684 | unsigned long vpsr; | ||
685 | struct kvm_pt_regs *regs = vcpu_regs(vcpu); | ||
686 | |||
687 | h_pending = highest_pending_irq(vcpu); | ||
688 | if (h_pending == NULL_VECTOR) { | ||
689 | update_vhpi(vcpu, NULL_VECTOR); | ||
690 | return; | ||
691 | } | ||
692 | h_inservice = highest_inservice_irq(vcpu); | ||
693 | |||
694 | vpsr = VCPU(vcpu, vpsr); | ||
695 | mask = irq_masked(vcpu, h_pending, h_inservice); | ||
696 | if ((vpsr & IA64_PSR_I) && IRQ_NO_MASKED == mask) { | ||
697 | isr = vpsr & IA64_PSR_RI; | ||
698 | update_vhpi(vcpu, h_pending); | ||
699 | reflect_interruption(0, isr, 0, 12, regs); /* EXT IRQ */ | ||
700 | } else if (mask == IRQ_MASKED_BY_INSVC) { | ||
701 | if (VCPU(vcpu, vhpi)) | ||
702 | update_vhpi(vcpu, NULL_VECTOR); | ||
703 | } else { | ||
704 | /* masked by vpsr.i or vtpr.*/ | ||
705 | update_vhpi(vcpu, h_pending); | ||
706 | } | ||
707 | } | ||
708 | |||
709 | static void generate_exirq(struct kvm_vcpu *vcpu) | ||
710 | { | ||
711 | unsigned vpsr; | ||
712 | uint64_t isr; | ||
713 | |||
714 | struct kvm_pt_regs *regs = vcpu_regs(vcpu); | ||
715 | |||
716 | vpsr = VCPU(vcpu, vpsr); | ||
717 | isr = vpsr & IA64_PSR_RI; | ||
718 | if (!(vpsr & IA64_PSR_IC)) | ||
719 | panic_vm(vcpu, "Trying to inject one IRQ with psr.ic=0\n"); | ||
720 | reflect_interruption(0, isr, 0, 12, regs); /* EXT IRQ */ | ||
721 | } | ||
722 | |||
723 | void vhpi_detection(struct kvm_vcpu *vcpu) | ||
724 | { | ||
725 | uint64_t threshold, vhpi; | ||
726 | union ia64_tpr vtpr; | ||
727 | struct ia64_psr vpsr; | ||
728 | |||
729 | vpsr = *(struct ia64_psr *)&VCPU(vcpu, vpsr); | ||
730 | vtpr.val = VCPU(vcpu, tpr); | ||
731 | |||
732 | threshold = ((!vpsr.i) << 5) | (vtpr.mmi << 4) | vtpr.mic; | ||
733 | vhpi = VCPU(vcpu, vhpi); | ||
734 | if (vhpi > threshold) { | ||
735 | /* interrupt actived*/ | ||
736 | generate_exirq(vcpu); | ||
737 | } | ||
738 | } | ||
739 | |||
740 | void leave_hypervisor_tail(void) | ||
741 | { | ||
742 | struct kvm_vcpu *v = current_vcpu; | ||
743 | |||
744 | if (VMX(v, timer_check)) { | ||
745 | VMX(v, timer_check) = 0; | ||
746 | if (VMX(v, itc_check)) { | ||
747 | if (vcpu_get_itc(v) > VCPU(v, itm)) { | ||
748 | if (!(VCPU(v, itv) & (1 << 16))) { | ||
749 | vcpu_pend_interrupt(v, VCPU(v, itv) | ||
750 | & 0xff); | ||
751 | VMX(v, itc_check) = 0; | ||
752 | } else { | ||
753 | v->arch.timer_pending = 1; | ||
754 | } | ||
755 | VMX(v, last_itc) = VCPU(v, itm) + 1; | ||
756 | } | ||
757 | } | ||
758 | } | ||
759 | |||
760 | rmb(); | ||
761 | if (v->arch.irq_new_pending) { | ||
762 | v->arch.irq_new_pending = 0; | ||
763 | VMX(v, irq_check) = 0; | ||
764 | check_pending_irq(v); | ||
765 | return; | ||
766 | } | ||
767 | if (VMX(v, irq_check)) { | ||
768 | VMX(v, irq_check) = 0; | ||
769 | vhpi_detection(v); | ||
770 | } | ||
771 | } | ||
772 | |||
773 | static inline void handle_lds(struct kvm_pt_regs *regs) | ||
774 | { | ||
775 | regs->cr_ipsr |= IA64_PSR_ED; | ||
776 | } | ||
777 | |||
778 | void physical_tlb_miss(struct kvm_vcpu *vcpu, unsigned long vadr, int type) | ||
779 | { | ||
780 | unsigned long pte; | ||
781 | union ia64_rr rr; | ||
782 | |||
783 | rr.val = ia64_get_rr(vadr); | ||
784 | pte = vadr & _PAGE_PPN_MASK; | ||
785 | pte = pte | PHY_PAGE_WB; | ||
786 | thash_vhpt_insert(vcpu, pte, (u64)(rr.ps << 2), vadr, type); | ||
787 | return; | ||
788 | } | ||
789 | |||
790 | void kvm_page_fault(u64 vadr , u64 vec, struct kvm_pt_regs *regs) | ||
791 | { | ||
792 | unsigned long vpsr; | ||
793 | int type; | ||
794 | |||
795 | u64 vhpt_adr, gppa, pteval, rr, itir; | ||
796 | union ia64_isr misr; | ||
797 | union ia64_pta vpta; | ||
798 | struct thash_data *data; | ||
799 | struct kvm_vcpu *v = current_vcpu; | ||
800 | |||
801 | vpsr = VCPU(v, vpsr); | ||
802 | misr.val = VMX(v, cr_isr); | ||
803 | |||
804 | type = vec; | ||
805 | |||
806 | if (is_physical_mode(v) && (!(vadr << 1 >> 62))) { | ||
807 | if (vec == 2) { | ||
808 | if (__gpfn_is_io((vadr << 1) >> (PAGE_SHIFT + 1))) { | ||
809 | emulate_io_inst(v, ((vadr << 1) >> 1), 4); | ||
810 | return; | ||
811 | } | ||
812 | } | ||
813 | physical_tlb_miss(v, vadr, type); | ||
814 | return; | ||
815 | } | ||
816 | data = vtlb_lookup(v, vadr, type); | ||
817 | if (data != 0) { | ||
818 | if (type == D_TLB) { | ||
819 | gppa = (vadr & ((1UL << data->ps) - 1)) | ||
820 | + (data->ppn >> (data->ps - 12) << data->ps); | ||
821 | if (__gpfn_is_io(gppa >> PAGE_SHIFT)) { | ||
822 | if (data->pl >= ((regs->cr_ipsr >> | ||
823 | IA64_PSR_CPL0_BIT) & 3)) | ||
824 | emulate_io_inst(v, gppa, data->ma); | ||
825 | else { | ||
826 | vcpu_set_isr(v, misr.val); | ||
827 | data_access_rights(v, vadr); | ||
828 | } | ||
829 | return ; | ||
830 | } | ||
831 | } | ||
832 | thash_vhpt_insert(v, data->page_flags, data->itir, vadr, type); | ||
833 | |||
834 | } else if (type == D_TLB) { | ||
835 | if (misr.sp) { | ||
836 | handle_lds(regs); | ||
837 | return; | ||
838 | } | ||
839 | |||
840 | rr = vcpu_get_rr(v, vadr); | ||
841 | itir = rr & (RR_RID_MASK | RR_PS_MASK); | ||
842 | |||
843 | if (!vhpt_enabled(v, vadr, misr.rs ? RSE_REF : DATA_REF)) { | ||
844 | if (vpsr & IA64_PSR_IC) { | ||
845 | vcpu_set_isr(v, misr.val); | ||
846 | alt_dtlb(v, vadr); | ||
847 | } else { | ||
848 | nested_dtlb(v); | ||
849 | } | ||
850 | return ; | ||
851 | } | ||
852 | |||
853 | vpta.val = vcpu_get_pta(v); | ||
854 | /* avoid recursively walking (short format) VHPT */ | ||
855 | |||
856 | vhpt_adr = vcpu_thash(v, vadr); | ||
857 | if (!guest_vhpt_lookup(vhpt_adr, &pteval)) { | ||
858 | /* VHPT successfully read. */ | ||
859 | if (!(pteval & _PAGE_P)) { | ||
860 | if (vpsr & IA64_PSR_IC) { | ||
861 | vcpu_set_isr(v, misr.val); | ||
862 | dtlb_fault(v, vadr); | ||
863 | } else { | ||
864 | nested_dtlb(v); | ||
865 | } | ||
866 | } else if ((pteval & _PAGE_MA_MASK) != _PAGE_MA_ST) { | ||
867 | thash_purge_and_insert(v, pteval, itir, | ||
868 | vadr, D_TLB); | ||
869 | } else if (vpsr & IA64_PSR_IC) { | ||
870 | vcpu_set_isr(v, misr.val); | ||
871 | dtlb_fault(v, vadr); | ||
872 | } else { | ||
873 | nested_dtlb(v); | ||
874 | } | ||
875 | } else { | ||
876 | /* Can't read VHPT. */ | ||
877 | if (vpsr & IA64_PSR_IC) { | ||
878 | vcpu_set_isr(v, misr.val); | ||
879 | dvhpt_fault(v, vadr); | ||
880 | } else { | ||
881 | nested_dtlb(v); | ||
882 | } | ||
883 | } | ||
884 | } else if (type == I_TLB) { | ||
885 | if (!(vpsr & IA64_PSR_IC)) | ||
886 | misr.ni = 1; | ||
887 | if (!vhpt_enabled(v, vadr, INST_REF)) { | ||
888 | vcpu_set_isr(v, misr.val); | ||
889 | alt_itlb(v, vadr); | ||
890 | return; | ||
891 | } | ||
892 | |||
893 | vpta.val = vcpu_get_pta(v); | ||
894 | |||
895 | vhpt_adr = vcpu_thash(v, vadr); | ||
896 | if (!guest_vhpt_lookup(vhpt_adr, &pteval)) { | ||
897 | /* VHPT successfully read. */ | ||
898 | if (pteval & _PAGE_P) { | ||
899 | if ((pteval & _PAGE_MA_MASK) == _PAGE_MA_ST) { | ||
900 | vcpu_set_isr(v, misr.val); | ||
901 | itlb_fault(v, vadr); | ||
902 | return ; | ||
903 | } | ||
904 | rr = vcpu_get_rr(v, vadr); | ||
905 | itir = rr & (RR_RID_MASK | RR_PS_MASK); | ||
906 | thash_purge_and_insert(v, pteval, itir, | ||
907 | vadr, I_TLB); | ||
908 | } else { | ||
909 | vcpu_set_isr(v, misr.val); | ||
910 | inst_page_not_present(v, vadr); | ||
911 | } | ||
912 | } else { | ||
913 | vcpu_set_isr(v, misr.val); | ||
914 | ivhpt_fault(v, vadr); | ||
915 | } | ||
916 | } | ||
917 | } | ||
918 | |||
919 | void kvm_vexirq(struct kvm_vcpu *vcpu) | ||
920 | { | ||
921 | u64 vpsr, isr; | ||
922 | struct kvm_pt_regs *regs; | ||
923 | |||
924 | regs = vcpu_regs(vcpu); | ||
925 | vpsr = VCPU(vcpu, vpsr); | ||
926 | isr = vpsr & IA64_PSR_RI; | ||
927 | reflect_interruption(0, isr, 0, 12, regs); /*EXT IRQ*/ | ||
928 | } | ||
929 | |||
930 | void kvm_ia64_handle_irq(struct kvm_vcpu *v) | ||
931 | { | ||
932 | struct exit_ctl_data *p = &v->arch.exit_data; | ||
933 | long psr; | ||
934 | |||
935 | local_irq_save(psr); | ||
936 | p->exit_reason = EXIT_REASON_EXTERNAL_INTERRUPT; | ||
937 | vmm_transition(v); | ||
938 | local_irq_restore(psr); | ||
939 | |||
940 | VMX(v, timer_check) = 1; | ||
941 | |||
942 | } | ||
943 | |||
944 | static void ptc_ga_remote_func(struct kvm_vcpu *v, int pos) | ||
945 | { | ||
946 | u64 oldrid, moldrid, oldpsbits, vaddr; | ||
947 | struct kvm_ptc_g *p = &v->arch.ptc_g_data[pos]; | ||
948 | vaddr = p->vaddr; | ||
949 | |||
950 | oldrid = VMX(v, vrr[0]); | ||
951 | VMX(v, vrr[0]) = p->rr; | ||
952 | oldpsbits = VMX(v, psbits[0]); | ||
953 | VMX(v, psbits[0]) = VMX(v, psbits[REGION_NUMBER(vaddr)]); | ||
954 | moldrid = ia64_get_rr(0x0); | ||
955 | ia64_set_rr(0x0, vrrtomrr(p->rr)); | ||
956 | ia64_srlz_d(); | ||
957 | |||
958 | vaddr = PAGEALIGN(vaddr, p->ps); | ||
959 | thash_purge_entries_remote(v, vaddr, p->ps); | ||
960 | |||
961 | VMX(v, vrr[0]) = oldrid; | ||
962 | VMX(v, psbits[0]) = oldpsbits; | ||
963 | ia64_set_rr(0x0, moldrid); | ||
964 | ia64_dv_serialize_data(); | ||
965 | } | ||
966 | |||
967 | static void vcpu_do_resume(struct kvm_vcpu *vcpu) | ||
968 | { | ||
969 | /*Re-init VHPT and VTLB once from resume*/ | ||
970 | vcpu->arch.vhpt.num = VHPT_NUM_ENTRIES; | ||
971 | thash_init(&vcpu->arch.vhpt, VHPT_SHIFT); | ||
972 | vcpu->arch.vtlb.num = VTLB_NUM_ENTRIES; | ||
973 | thash_init(&vcpu->arch.vtlb, VTLB_SHIFT); | ||
974 | |||
975 | ia64_set_pta(vcpu->arch.vhpt.pta.val); | ||
976 | } | ||
977 | |||
978 | static void vmm_sanity_check(struct kvm_vcpu *vcpu) | ||
979 | { | ||
980 | struct exit_ctl_data *p = &vcpu->arch.exit_data; | ||
981 | |||
982 | if (!vmm_sanity && p->exit_reason != EXIT_REASON_DEBUG) { | ||
983 | panic_vm(vcpu, "Failed to do vmm sanity check," | ||
984 | "it maybe caused by crashed vmm!!\n\n"); | ||
985 | } | ||
986 | } | ||
987 | |||
988 | static void kvm_do_resume_op(struct kvm_vcpu *vcpu) | ||
989 | { | ||
990 | vmm_sanity_check(vcpu); /*Guarantee vcpu running on healthy vmm!*/ | ||
991 | |||
992 | if (test_and_clear_bit(KVM_REQ_RESUME, &vcpu->requests)) { | ||
993 | vcpu_do_resume(vcpu); | ||
994 | return; | ||
995 | } | ||
996 | |||
997 | if (unlikely(test_and_clear_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests))) { | ||
998 | thash_purge_all(vcpu); | ||
999 | return; | ||
1000 | } | ||
1001 | |||
1002 | if (test_and_clear_bit(KVM_REQ_PTC_G, &vcpu->requests)) { | ||
1003 | while (vcpu->arch.ptc_g_count > 0) | ||
1004 | ptc_ga_remote_func(vcpu, --vcpu->arch.ptc_g_count); | ||
1005 | } | ||
1006 | } | ||
1007 | |||
1008 | void vmm_transition(struct kvm_vcpu *vcpu) | ||
1009 | { | ||
1010 | ia64_call_vsa(PAL_VPS_SAVE, (unsigned long)vcpu->arch.vpd, | ||
1011 | 1, 0, 0, 0, 0, 0); | ||
1012 | vmm_trampoline(&vcpu->arch.guest, &vcpu->arch.host); | ||
1013 | ia64_call_vsa(PAL_VPS_RESTORE, (unsigned long)vcpu->arch.vpd, | ||
1014 | 1, 0, 0, 0, 0, 0); | ||
1015 | kvm_do_resume_op(vcpu); | ||
1016 | } | ||
1017 | |||
1018 | void vmm_panic_handler(u64 vec) | ||
1019 | { | ||
1020 | struct kvm_vcpu *vcpu = current_vcpu; | ||
1021 | vmm_sanity = 0; | ||
1022 | panic_vm(vcpu, "Unexpected interruption occurs in VMM, vector:0x%lx\n", | ||
1023 | vec2off[vec]); | ||
1024 | } | ||
diff --git a/arch/ia64/kvm/trampoline.S b/arch/ia64/kvm/trampoline.S deleted file mode 100644 index 30897d44d61e..000000000000 --- a/arch/ia64/kvm/trampoline.S +++ /dev/null | |||
@@ -1,1038 +0,0 @@ | |||
1 | /* Save all processor states | ||
2 | * | ||
3 | * Copyright (c) 2007 Fleming Feng <fleming.feng@intel.com> | ||
4 | * Copyright (c) 2007 Anthony Xu <anthony.xu@intel.com> | ||
5 | */ | ||
6 | |||
7 | #include <asm/asmmacro.h> | ||
8 | #include "asm-offsets.h" | ||
9 | |||
10 | |||
11 | #define CTX(name) VMM_CTX_##name##_OFFSET | ||
12 | |||
13 | /* | ||
14 | * r32: context_t base address | ||
15 | */ | ||
16 | #define SAVE_BRANCH_REGS \ | ||
17 | add r2 = CTX(B0),r32; \ | ||
18 | add r3 = CTX(B1),r32; \ | ||
19 | mov r16 = b0; \ | ||
20 | mov r17 = b1; \ | ||
21 | ;; \ | ||
22 | st8 [r2]=r16,16; \ | ||
23 | st8 [r3]=r17,16; \ | ||
24 | ;; \ | ||
25 | mov r16 = b2; \ | ||
26 | mov r17 = b3; \ | ||
27 | ;; \ | ||
28 | st8 [r2]=r16,16; \ | ||
29 | st8 [r3]=r17,16; \ | ||
30 | ;; \ | ||
31 | mov r16 = b4; \ | ||
32 | mov r17 = b5; \ | ||
33 | ;; \ | ||
34 | st8 [r2]=r16; \ | ||
35 | st8 [r3]=r17; \ | ||
36 | ;; | ||
37 | |||
38 | /* | ||
39 | * r33: context_t base address | ||
40 | */ | ||
41 | #define RESTORE_BRANCH_REGS \ | ||
42 | add r2 = CTX(B0),r33; \ | ||
43 | add r3 = CTX(B1),r33; \ | ||
44 | ;; \ | ||
45 | ld8 r16=[r2],16; \ | ||
46 | ld8 r17=[r3],16; \ | ||
47 | ;; \ | ||
48 | mov b0 = r16; \ | ||
49 | mov b1 = r17; \ | ||
50 | ;; \ | ||
51 | ld8 r16=[r2],16; \ | ||
52 | ld8 r17=[r3],16; \ | ||
53 | ;; \ | ||
54 | mov b2 = r16; \ | ||
55 | mov b3 = r17; \ | ||
56 | ;; \ | ||
57 | ld8 r16=[r2]; \ | ||
58 | ld8 r17=[r3]; \ | ||
59 | ;; \ | ||
60 | mov b4=r16; \ | ||
61 | mov b5=r17; \ | ||
62 | ;; | ||
63 | |||
64 | |||
65 | /* | ||
66 | * r32: context_t base address | ||
67 | * bsw == 1 | ||
68 | * Save all bank1 general registers, r4 ~ r7 | ||
69 | */ | ||
70 | #define SAVE_GENERAL_REGS \ | ||
71 | add r2=CTX(R4),r32; \ | ||
72 | add r3=CTX(R5),r32; \ | ||
73 | ;; \ | ||
74 | .mem.offset 0,0; \ | ||
75 | st8.spill [r2]=r4,16; \ | ||
76 | .mem.offset 8,0; \ | ||
77 | st8.spill [r3]=r5,16; \ | ||
78 | ;; \ | ||
79 | .mem.offset 0,0; \ | ||
80 | st8.spill [r2]=r6,48; \ | ||
81 | .mem.offset 8,0; \ | ||
82 | st8.spill [r3]=r7,48; \ | ||
83 | ;; \ | ||
84 | .mem.offset 0,0; \ | ||
85 | st8.spill [r2]=r12; \ | ||
86 | .mem.offset 8,0; \ | ||
87 | st8.spill [r3]=r13; \ | ||
88 | ;; | ||
89 | |||
90 | /* | ||
91 | * r33: context_t base address | ||
92 | * bsw == 1 | ||
93 | */ | ||
94 | #define RESTORE_GENERAL_REGS \ | ||
95 | add r2=CTX(R4),r33; \ | ||
96 | add r3=CTX(R5),r33; \ | ||
97 | ;; \ | ||
98 | ld8.fill r4=[r2],16; \ | ||
99 | ld8.fill r5=[r3],16; \ | ||
100 | ;; \ | ||
101 | ld8.fill r6=[r2],48; \ | ||
102 | ld8.fill r7=[r3],48; \ | ||
103 | ;; \ | ||
104 | ld8.fill r12=[r2]; \ | ||
105 | ld8.fill r13 =[r3]; \ | ||
106 | ;; | ||
107 | |||
108 | |||
109 | |||
110 | |||
111 | /* | ||
112 | * r32: context_t base address | ||
113 | */ | ||
114 | #define SAVE_KERNEL_REGS \ | ||
115 | add r2 = CTX(KR0),r32; \ | ||
116 | add r3 = CTX(KR1),r32; \ | ||
117 | mov r16 = ar.k0; \ | ||
118 | mov r17 = ar.k1; \ | ||
119 | ;; \ | ||
120 | st8 [r2] = r16,16; \ | ||
121 | st8 [r3] = r17,16; \ | ||
122 | ;; \ | ||
123 | mov r16 = ar.k2; \ | ||
124 | mov r17 = ar.k3; \ | ||
125 | ;; \ | ||
126 | st8 [r2] = r16,16; \ | ||
127 | st8 [r3] = r17,16; \ | ||
128 | ;; \ | ||
129 | mov r16 = ar.k4; \ | ||
130 | mov r17 = ar.k5; \ | ||
131 | ;; \ | ||
132 | st8 [r2] = r16,16; \ | ||
133 | st8 [r3] = r17,16; \ | ||
134 | ;; \ | ||
135 | mov r16 = ar.k6; \ | ||
136 | mov r17 = ar.k7; \ | ||
137 | ;; \ | ||
138 | st8 [r2] = r16; \ | ||
139 | st8 [r3] = r17; \ | ||
140 | ;; | ||
141 | |||
142 | |||
143 | |||
144 | /* | ||
145 | * r33: context_t base address | ||
146 | */ | ||
147 | #define RESTORE_KERNEL_REGS \ | ||
148 | add r2 = CTX(KR0),r33; \ | ||
149 | add r3 = CTX(KR1),r33; \ | ||
150 | ;; \ | ||
151 | ld8 r16=[r2],16; \ | ||
152 | ld8 r17=[r3],16; \ | ||
153 | ;; \ | ||
154 | mov ar.k0=r16; \ | ||
155 | mov ar.k1=r17; \ | ||
156 | ;; \ | ||
157 | ld8 r16=[r2],16; \ | ||
158 | ld8 r17=[r3],16; \ | ||
159 | ;; \ | ||
160 | mov ar.k2=r16; \ | ||
161 | mov ar.k3=r17; \ | ||
162 | ;; \ | ||
163 | ld8 r16=[r2],16; \ | ||
164 | ld8 r17=[r3],16; \ | ||
165 | ;; \ | ||
166 | mov ar.k4=r16; \ | ||
167 | mov ar.k5=r17; \ | ||
168 | ;; \ | ||
169 | ld8 r16=[r2],16; \ | ||
170 | ld8 r17=[r3],16; \ | ||
171 | ;; \ | ||
172 | mov ar.k6=r16; \ | ||
173 | mov ar.k7=r17; \ | ||
174 | ;; | ||
175 | |||
176 | |||
177 | |||
178 | /* | ||
179 | * r32: context_t base address | ||
180 | */ | ||
181 | #define SAVE_APP_REGS \ | ||
182 | add r2 = CTX(BSPSTORE),r32; \ | ||
183 | mov r16 = ar.bspstore; \ | ||
184 | ;; \ | ||
185 | st8 [r2] = r16,CTX(RNAT)-CTX(BSPSTORE);\ | ||
186 | mov r16 = ar.rnat; \ | ||
187 | ;; \ | ||
188 | st8 [r2] = r16,CTX(FCR)-CTX(RNAT); \ | ||
189 | mov r16 = ar.fcr; \ | ||
190 | ;; \ | ||
191 | st8 [r2] = r16,CTX(EFLAG)-CTX(FCR); \ | ||
192 | mov r16 = ar.eflag; \ | ||
193 | ;; \ | ||
194 | st8 [r2] = r16,CTX(CFLG)-CTX(EFLAG); \ | ||
195 | mov r16 = ar.cflg; \ | ||
196 | ;; \ | ||
197 | st8 [r2] = r16,CTX(FSR)-CTX(CFLG); \ | ||
198 | mov r16 = ar.fsr; \ | ||
199 | ;; \ | ||
200 | st8 [r2] = r16,CTX(FIR)-CTX(FSR); \ | ||
201 | mov r16 = ar.fir; \ | ||
202 | ;; \ | ||
203 | st8 [r2] = r16,CTX(FDR)-CTX(FIR); \ | ||
204 | mov r16 = ar.fdr; \ | ||
205 | ;; \ | ||
206 | st8 [r2] = r16,CTX(UNAT)-CTX(FDR); \ | ||
207 | mov r16 = ar.unat; \ | ||
208 | ;; \ | ||
209 | st8 [r2] = r16,CTX(FPSR)-CTX(UNAT); \ | ||
210 | mov r16 = ar.fpsr; \ | ||
211 | ;; \ | ||
212 | st8 [r2] = r16,CTX(PFS)-CTX(FPSR); \ | ||
213 | mov r16 = ar.pfs; \ | ||
214 | ;; \ | ||
215 | st8 [r2] = r16,CTX(LC)-CTX(PFS); \ | ||
216 | mov r16 = ar.lc; \ | ||
217 | ;; \ | ||
218 | st8 [r2] = r16; \ | ||
219 | ;; | ||
220 | |||
221 | /* | ||
222 | * r33: context_t base address | ||
223 | */ | ||
224 | #define RESTORE_APP_REGS \ | ||
225 | add r2=CTX(BSPSTORE),r33; \ | ||
226 | ;; \ | ||
227 | ld8 r16=[r2],CTX(RNAT)-CTX(BSPSTORE); \ | ||
228 | ;; \ | ||
229 | mov ar.bspstore=r16; \ | ||
230 | ld8 r16=[r2],CTX(FCR)-CTX(RNAT); \ | ||
231 | ;; \ | ||
232 | mov ar.rnat=r16; \ | ||
233 | ld8 r16=[r2],CTX(EFLAG)-CTX(FCR); \ | ||
234 | ;; \ | ||
235 | mov ar.fcr=r16; \ | ||
236 | ld8 r16=[r2],CTX(CFLG)-CTX(EFLAG); \ | ||
237 | ;; \ | ||
238 | mov ar.eflag=r16; \ | ||
239 | ld8 r16=[r2],CTX(FSR)-CTX(CFLG); \ | ||
240 | ;; \ | ||
241 | mov ar.cflg=r16; \ | ||
242 | ld8 r16=[r2],CTX(FIR)-CTX(FSR); \ | ||
243 | ;; \ | ||
244 | mov ar.fsr=r16; \ | ||
245 | ld8 r16=[r2],CTX(FDR)-CTX(FIR); \ | ||
246 | ;; \ | ||
247 | mov ar.fir=r16; \ | ||
248 | ld8 r16=[r2],CTX(UNAT)-CTX(FDR); \ | ||
249 | ;; \ | ||
250 | mov ar.fdr=r16; \ | ||
251 | ld8 r16=[r2],CTX(FPSR)-CTX(UNAT); \ | ||
252 | ;; \ | ||
253 | mov ar.unat=r16; \ | ||
254 | ld8 r16=[r2],CTX(PFS)-CTX(FPSR); \ | ||
255 | ;; \ | ||
256 | mov ar.fpsr=r16; \ | ||
257 | ld8 r16=[r2],CTX(LC)-CTX(PFS); \ | ||
258 | ;; \ | ||
259 | mov ar.pfs=r16; \ | ||
260 | ld8 r16=[r2]; \ | ||
261 | ;; \ | ||
262 | mov ar.lc=r16; \ | ||
263 | ;; | ||
264 | |||
265 | /* | ||
266 | * r32: context_t base address | ||
267 | */ | ||
268 | #define SAVE_CTL_REGS \ | ||
269 | add r2 = CTX(DCR),r32; \ | ||
270 | mov r16 = cr.dcr; \ | ||
271 | ;; \ | ||
272 | st8 [r2] = r16,CTX(IVA)-CTX(DCR); \ | ||
273 | ;; \ | ||
274 | mov r16 = cr.iva; \ | ||
275 | ;; \ | ||
276 | st8 [r2] = r16,CTX(PTA)-CTX(IVA); \ | ||
277 | ;; \ | ||
278 | mov r16 = cr.pta; \ | ||
279 | ;; \ | ||
280 | st8 [r2] = r16 ; \ | ||
281 | ;; | ||
282 | |||
283 | /* | ||
284 | * r33: context_t base address | ||
285 | */ | ||
286 | #define RESTORE_CTL_REGS \ | ||
287 | add r2 = CTX(DCR),r33; \ | ||
288 | ;; \ | ||
289 | ld8 r16 = [r2],CTX(IVA)-CTX(DCR); \ | ||
290 | ;; \ | ||
291 | mov cr.dcr = r16; \ | ||
292 | dv_serialize_data; \ | ||
293 | ;; \ | ||
294 | ld8 r16 = [r2],CTX(PTA)-CTX(IVA); \ | ||
295 | ;; \ | ||
296 | mov cr.iva = r16; \ | ||
297 | dv_serialize_data; \ | ||
298 | ;; \ | ||
299 | ld8 r16 = [r2]; \ | ||
300 | ;; \ | ||
301 | mov cr.pta = r16; \ | ||
302 | dv_serialize_data; \ | ||
303 | ;; | ||
304 | |||
305 | |||
306 | /* | ||
307 | * r32: context_t base address | ||
308 | */ | ||
309 | #define SAVE_REGION_REGS \ | ||
310 | add r2=CTX(RR0),r32; \ | ||
311 | mov r16=rr[r0]; \ | ||
312 | dep.z r18=1,61,3; \ | ||
313 | ;; \ | ||
314 | st8 [r2]=r16,8; \ | ||
315 | mov r17=rr[r18]; \ | ||
316 | dep.z r18=2,61,3; \ | ||
317 | ;; \ | ||
318 | st8 [r2]=r17,8; \ | ||
319 | mov r16=rr[r18]; \ | ||
320 | dep.z r18=3,61,3; \ | ||
321 | ;; \ | ||
322 | st8 [r2]=r16,8; \ | ||
323 | mov r17=rr[r18]; \ | ||
324 | dep.z r18=4,61,3; \ | ||
325 | ;; \ | ||
326 | st8 [r2]=r17,8; \ | ||
327 | mov r16=rr[r18]; \ | ||
328 | dep.z r18=5,61,3; \ | ||
329 | ;; \ | ||
330 | st8 [r2]=r16,8; \ | ||
331 | mov r17=rr[r18]; \ | ||
332 | dep.z r18=7,61,3; \ | ||
333 | ;; \ | ||
334 | st8 [r2]=r17,16; \ | ||
335 | mov r16=rr[r18]; \ | ||
336 | ;; \ | ||
337 | st8 [r2]=r16,8; \ | ||
338 | ;; | ||
339 | |||
340 | /* | ||
341 | * r33:context_t base address | ||
342 | */ | ||
343 | #define RESTORE_REGION_REGS \ | ||
344 | add r2=CTX(RR0),r33;\ | ||
345 | mov r18=r0; \ | ||
346 | ;; \ | ||
347 | ld8 r20=[r2],8; \ | ||
348 | ;; /* rr0 */ \ | ||
349 | ld8 r21=[r2],8; \ | ||
350 | ;; /* rr1 */ \ | ||
351 | ld8 r22=[r2],8; \ | ||
352 | ;; /* rr2 */ \ | ||
353 | ld8 r23=[r2],8; \ | ||
354 | ;; /* rr3 */ \ | ||
355 | ld8 r24=[r2],8; \ | ||
356 | ;; /* rr4 */ \ | ||
357 | ld8 r25=[r2],16; \ | ||
358 | ;; /* rr5 */ \ | ||
359 | ld8 r27=[r2]; \ | ||
360 | ;; /* rr7 */ \ | ||
361 | mov rr[r18]=r20; \ | ||
362 | dep.z r18=1,61,3; \ | ||
363 | ;; /* rr1 */ \ | ||
364 | mov rr[r18]=r21; \ | ||
365 | dep.z r18=2,61,3; \ | ||
366 | ;; /* rr2 */ \ | ||
367 | mov rr[r18]=r22; \ | ||
368 | dep.z r18=3,61,3; \ | ||
369 | ;; /* rr3 */ \ | ||
370 | mov rr[r18]=r23; \ | ||
371 | dep.z r18=4,61,3; \ | ||
372 | ;; /* rr4 */ \ | ||
373 | mov rr[r18]=r24; \ | ||
374 | dep.z r18=5,61,3; \ | ||
375 | ;; /* rr5 */ \ | ||
376 | mov rr[r18]=r25; \ | ||
377 | dep.z r18=7,61,3; \ | ||
378 | ;; /* rr7 */ \ | ||
379 | mov rr[r18]=r27; \ | ||
380 | ;; \ | ||
381 | srlz.i; \ | ||
382 | ;; | ||
383 | |||
384 | |||
385 | |||
386 | /* | ||
387 | * r32: context_t base address | ||
388 | * r36~r39:scratch registers | ||
389 | */ | ||
390 | #define SAVE_DEBUG_REGS \ | ||
391 | add r2=CTX(IBR0),r32; \ | ||
392 | add r3=CTX(DBR0),r32; \ | ||
393 | mov r16=ibr[r0]; \ | ||
394 | mov r17=dbr[r0]; \ | ||
395 | ;; \ | ||
396 | st8 [r2]=r16,8; \ | ||
397 | st8 [r3]=r17,8; \ | ||
398 | add r18=1,r0; \ | ||
399 | ;; \ | ||
400 | mov r16=ibr[r18]; \ | ||
401 | mov r17=dbr[r18]; \ | ||
402 | ;; \ | ||
403 | st8 [r2]=r16,8; \ | ||
404 | st8 [r3]=r17,8; \ | ||
405 | add r18=2,r0; \ | ||
406 | ;; \ | ||
407 | mov r16=ibr[r18]; \ | ||
408 | mov r17=dbr[r18]; \ | ||
409 | ;; \ | ||
410 | st8 [r2]=r16,8; \ | ||
411 | st8 [r3]=r17,8; \ | ||
412 | add r18=2,r0; \ | ||
413 | ;; \ | ||
414 | mov r16=ibr[r18]; \ | ||
415 | mov r17=dbr[r18]; \ | ||
416 | ;; \ | ||
417 | st8 [r2]=r16,8; \ | ||
418 | st8 [r3]=r17,8; \ | ||
419 | add r18=3,r0; \ | ||
420 | ;; \ | ||
421 | mov r16=ibr[r18]; \ | ||
422 | mov r17=dbr[r18]; \ | ||
423 | ;; \ | ||
424 | st8 [r2]=r16,8; \ | ||
425 | st8 [r3]=r17,8; \ | ||
426 | add r18=4,r0; \ | ||
427 | ;; \ | ||
428 | mov r16=ibr[r18]; \ | ||
429 | mov r17=dbr[r18]; \ | ||
430 | ;; \ | ||
431 | st8 [r2]=r16,8; \ | ||
432 | st8 [r3]=r17,8; \ | ||
433 | add r18=5,r0; \ | ||
434 | ;; \ | ||
435 | mov r16=ibr[r18]; \ | ||
436 | mov r17=dbr[r18]; \ | ||
437 | ;; \ | ||
438 | st8 [r2]=r16,8; \ | ||
439 | st8 [r3]=r17,8; \ | ||
440 | add r18=6,r0; \ | ||
441 | ;; \ | ||
442 | mov r16=ibr[r18]; \ | ||
443 | mov r17=dbr[r18]; \ | ||
444 | ;; \ | ||
445 | st8 [r2]=r16,8; \ | ||
446 | st8 [r3]=r17,8; \ | ||
447 | add r18=7,r0; \ | ||
448 | ;; \ | ||
449 | mov r16=ibr[r18]; \ | ||
450 | mov r17=dbr[r18]; \ | ||
451 | ;; \ | ||
452 | st8 [r2]=r16,8; \ | ||
453 | st8 [r3]=r17,8; \ | ||
454 | ;; | ||
455 | |||
456 | |||
457 | /* | ||
458 | * r33: point to context_t structure | ||
459 | * ar.lc are corrupted. | ||
460 | */ | ||
461 | #define RESTORE_DEBUG_REGS \ | ||
462 | add r2=CTX(IBR0),r33; \ | ||
463 | add r3=CTX(DBR0),r33; \ | ||
464 | mov r16=7; \ | ||
465 | mov r17=r0; \ | ||
466 | ;; \ | ||
467 | mov ar.lc = r16; \ | ||
468 | ;; \ | ||
469 | 1: \ | ||
470 | ld8 r18=[r2],8; \ | ||
471 | ld8 r19=[r3],8; \ | ||
472 | ;; \ | ||
473 | mov ibr[r17]=r18; \ | ||
474 | mov dbr[r17]=r19; \ | ||
475 | ;; \ | ||
476 | srlz.i; \ | ||
477 | ;; \ | ||
478 | add r17=1,r17; \ | ||
479 | br.cloop.sptk 1b; \ | ||
480 | ;; | ||
481 | |||
482 | |||
483 | /* | ||
484 | * r32: context_t base address | ||
485 | */ | ||
486 | #define SAVE_FPU_LOW \ | ||
487 | add r2=CTX(F2),r32; \ | ||
488 | add r3=CTX(F3),r32; \ | ||
489 | ;; \ | ||
490 | stf.spill.nta [r2]=f2,32; \ | ||
491 | stf.spill.nta [r3]=f3,32; \ | ||
492 | ;; \ | ||
493 | stf.spill.nta [r2]=f4,32; \ | ||
494 | stf.spill.nta [r3]=f5,32; \ | ||
495 | ;; \ | ||
496 | stf.spill.nta [r2]=f6,32; \ | ||
497 | stf.spill.nta [r3]=f7,32; \ | ||
498 | ;; \ | ||
499 | stf.spill.nta [r2]=f8,32; \ | ||
500 | stf.spill.nta [r3]=f9,32; \ | ||
501 | ;; \ | ||
502 | stf.spill.nta [r2]=f10,32; \ | ||
503 | stf.spill.nta [r3]=f11,32; \ | ||
504 | ;; \ | ||
505 | stf.spill.nta [r2]=f12,32; \ | ||
506 | stf.spill.nta [r3]=f13,32; \ | ||
507 | ;; \ | ||
508 | stf.spill.nta [r2]=f14,32; \ | ||
509 | stf.spill.nta [r3]=f15,32; \ | ||
510 | ;; \ | ||
511 | stf.spill.nta [r2]=f16,32; \ | ||
512 | stf.spill.nta [r3]=f17,32; \ | ||
513 | ;; \ | ||
514 | stf.spill.nta [r2]=f18,32; \ | ||
515 | stf.spill.nta [r3]=f19,32; \ | ||
516 | ;; \ | ||
517 | stf.spill.nta [r2]=f20,32; \ | ||
518 | stf.spill.nta [r3]=f21,32; \ | ||
519 | ;; \ | ||
520 | stf.spill.nta [r2]=f22,32; \ | ||
521 | stf.spill.nta [r3]=f23,32; \ | ||
522 | ;; \ | ||
523 | stf.spill.nta [r2]=f24,32; \ | ||
524 | stf.spill.nta [r3]=f25,32; \ | ||
525 | ;; \ | ||
526 | stf.spill.nta [r2]=f26,32; \ | ||
527 | stf.spill.nta [r3]=f27,32; \ | ||
528 | ;; \ | ||
529 | stf.spill.nta [r2]=f28,32; \ | ||
530 | stf.spill.nta [r3]=f29,32; \ | ||
531 | ;; \ | ||
532 | stf.spill.nta [r2]=f30; \ | ||
533 | stf.spill.nta [r3]=f31; \ | ||
534 | ;; | ||
535 | |||
536 | /* | ||
537 | * r32: context_t base address | ||
538 | */ | ||
539 | #define SAVE_FPU_HIGH \ | ||
540 | add r2=CTX(F32),r32; \ | ||
541 | add r3=CTX(F33),r32; \ | ||
542 | ;; \ | ||
543 | stf.spill.nta [r2]=f32,32; \ | ||
544 | stf.spill.nta [r3]=f33,32; \ | ||
545 | ;; \ | ||
546 | stf.spill.nta [r2]=f34,32; \ | ||
547 | stf.spill.nta [r3]=f35,32; \ | ||
548 | ;; \ | ||
549 | stf.spill.nta [r2]=f36,32; \ | ||
550 | stf.spill.nta [r3]=f37,32; \ | ||
551 | ;; \ | ||
552 | stf.spill.nta [r2]=f38,32; \ | ||
553 | stf.spill.nta [r3]=f39,32; \ | ||
554 | ;; \ | ||
555 | stf.spill.nta [r2]=f40,32; \ | ||
556 | stf.spill.nta [r3]=f41,32; \ | ||
557 | ;; \ | ||
558 | stf.spill.nta [r2]=f42,32; \ | ||
559 | stf.spill.nta [r3]=f43,32; \ | ||
560 | ;; \ | ||
561 | stf.spill.nta [r2]=f44,32; \ | ||
562 | stf.spill.nta [r3]=f45,32; \ | ||
563 | ;; \ | ||
564 | stf.spill.nta [r2]=f46,32; \ | ||
565 | stf.spill.nta [r3]=f47,32; \ | ||
566 | ;; \ | ||
567 | stf.spill.nta [r2]=f48,32; \ | ||
568 | stf.spill.nta [r3]=f49,32; \ | ||
569 | ;; \ | ||
570 | stf.spill.nta [r2]=f50,32; \ | ||
571 | stf.spill.nta [r3]=f51,32; \ | ||
572 | ;; \ | ||
573 | stf.spill.nta [r2]=f52,32; \ | ||
574 | stf.spill.nta [r3]=f53,32; \ | ||
575 | ;; \ | ||
576 | stf.spill.nta [r2]=f54,32; \ | ||
577 | stf.spill.nta [r3]=f55,32; \ | ||
578 | ;; \ | ||
579 | stf.spill.nta [r2]=f56,32; \ | ||
580 | stf.spill.nta [r3]=f57,32; \ | ||
581 | ;; \ | ||
582 | stf.spill.nta [r2]=f58,32; \ | ||
583 | stf.spill.nta [r3]=f59,32; \ | ||
584 | ;; \ | ||
585 | stf.spill.nta [r2]=f60,32; \ | ||
586 | stf.spill.nta [r3]=f61,32; \ | ||
587 | ;; \ | ||
588 | stf.spill.nta [r2]=f62,32; \ | ||
589 | stf.spill.nta [r3]=f63,32; \ | ||
590 | ;; \ | ||
591 | stf.spill.nta [r2]=f64,32; \ | ||
592 | stf.spill.nta [r3]=f65,32; \ | ||
593 | ;; \ | ||
594 | stf.spill.nta [r2]=f66,32; \ | ||
595 | stf.spill.nta [r3]=f67,32; \ | ||
596 | ;; \ | ||
597 | stf.spill.nta [r2]=f68,32; \ | ||
598 | stf.spill.nta [r3]=f69,32; \ | ||
599 | ;; \ | ||
600 | stf.spill.nta [r2]=f70,32; \ | ||
601 | stf.spill.nta [r3]=f71,32; \ | ||
602 | ;; \ | ||
603 | stf.spill.nta [r2]=f72,32; \ | ||
604 | stf.spill.nta [r3]=f73,32; \ | ||
605 | ;; \ | ||
606 | stf.spill.nta [r2]=f74,32; \ | ||
607 | stf.spill.nta [r3]=f75,32; \ | ||
608 | ;; \ | ||
609 | stf.spill.nta [r2]=f76,32; \ | ||
610 | stf.spill.nta [r3]=f77,32; \ | ||
611 | ;; \ | ||
612 | stf.spill.nta [r2]=f78,32; \ | ||
613 | stf.spill.nta [r3]=f79,32; \ | ||
614 | ;; \ | ||
615 | stf.spill.nta [r2]=f80,32; \ | ||
616 | stf.spill.nta [r3]=f81,32; \ | ||
617 | ;; \ | ||
618 | stf.spill.nta [r2]=f82,32; \ | ||
619 | stf.spill.nta [r3]=f83,32; \ | ||
620 | ;; \ | ||
621 | stf.spill.nta [r2]=f84,32; \ | ||
622 | stf.spill.nta [r3]=f85,32; \ | ||
623 | ;; \ | ||
624 | stf.spill.nta [r2]=f86,32; \ | ||
625 | stf.spill.nta [r3]=f87,32; \ | ||
626 | ;; \ | ||
627 | stf.spill.nta [r2]=f88,32; \ | ||
628 | stf.spill.nta [r3]=f89,32; \ | ||
629 | ;; \ | ||
630 | stf.spill.nta [r2]=f90,32; \ | ||
631 | stf.spill.nta [r3]=f91,32; \ | ||
632 | ;; \ | ||
633 | stf.spill.nta [r2]=f92,32; \ | ||
634 | stf.spill.nta [r3]=f93,32; \ | ||
635 | ;; \ | ||
636 | stf.spill.nta [r2]=f94,32; \ | ||
637 | stf.spill.nta [r3]=f95,32; \ | ||
638 | ;; \ | ||
639 | stf.spill.nta [r2]=f96,32; \ | ||
640 | stf.spill.nta [r3]=f97,32; \ | ||
641 | ;; \ | ||
642 | stf.spill.nta [r2]=f98,32; \ | ||
643 | stf.spill.nta [r3]=f99,32; \ | ||
644 | ;; \ | ||
645 | stf.spill.nta [r2]=f100,32; \ | ||
646 | stf.spill.nta [r3]=f101,32; \ | ||
647 | ;; \ | ||
648 | stf.spill.nta [r2]=f102,32; \ | ||
649 | stf.spill.nta [r3]=f103,32; \ | ||
650 | ;; \ | ||
651 | stf.spill.nta [r2]=f104,32; \ | ||
652 | stf.spill.nta [r3]=f105,32; \ | ||
653 | ;; \ | ||
654 | stf.spill.nta [r2]=f106,32; \ | ||
655 | stf.spill.nta [r3]=f107,32; \ | ||
656 | ;; \ | ||
657 | stf.spill.nta [r2]=f108,32; \ | ||
658 | stf.spill.nta [r3]=f109,32; \ | ||
659 | ;; \ | ||
660 | stf.spill.nta [r2]=f110,32; \ | ||
661 | stf.spill.nta [r3]=f111,32; \ | ||
662 | ;; \ | ||
663 | stf.spill.nta [r2]=f112,32; \ | ||
664 | stf.spill.nta [r3]=f113,32; \ | ||
665 | ;; \ | ||
666 | stf.spill.nta [r2]=f114,32; \ | ||
667 | stf.spill.nta [r3]=f115,32; \ | ||
668 | ;; \ | ||
669 | stf.spill.nta [r2]=f116,32; \ | ||
670 | stf.spill.nta [r3]=f117,32; \ | ||
671 | ;; \ | ||
672 | stf.spill.nta [r2]=f118,32; \ | ||
673 | stf.spill.nta [r3]=f119,32; \ | ||
674 | ;; \ | ||
675 | stf.spill.nta [r2]=f120,32; \ | ||
676 | stf.spill.nta [r3]=f121,32; \ | ||
677 | ;; \ | ||
678 | stf.spill.nta [r2]=f122,32; \ | ||
679 | stf.spill.nta [r3]=f123,32; \ | ||
680 | ;; \ | ||
681 | stf.spill.nta [r2]=f124,32; \ | ||
682 | stf.spill.nta [r3]=f125,32; \ | ||
683 | ;; \ | ||
684 | stf.spill.nta [r2]=f126; \ | ||
685 | stf.spill.nta [r3]=f127; \ | ||
686 | ;; | ||
687 | |||
688 | /* | ||
689 | * r33: point to context_t structure | ||
690 | */ | ||
691 | #define RESTORE_FPU_LOW \ | ||
692 | add r2 = CTX(F2), r33; \ | ||
693 | add r3 = CTX(F3), r33; \ | ||
694 | ;; \ | ||
695 | ldf.fill.nta f2 = [r2], 32; \ | ||
696 | ldf.fill.nta f3 = [r3], 32; \ | ||
697 | ;; \ | ||
698 | ldf.fill.nta f4 = [r2], 32; \ | ||
699 | ldf.fill.nta f5 = [r3], 32; \ | ||
700 | ;; \ | ||
701 | ldf.fill.nta f6 = [r2], 32; \ | ||
702 | ldf.fill.nta f7 = [r3], 32; \ | ||
703 | ;; \ | ||
704 | ldf.fill.nta f8 = [r2], 32; \ | ||
705 | ldf.fill.nta f9 = [r3], 32; \ | ||
706 | ;; \ | ||
707 | ldf.fill.nta f10 = [r2], 32; \ | ||
708 | ldf.fill.nta f11 = [r3], 32; \ | ||
709 | ;; \ | ||
710 | ldf.fill.nta f12 = [r2], 32; \ | ||
711 | ldf.fill.nta f13 = [r3], 32; \ | ||
712 | ;; \ | ||
713 | ldf.fill.nta f14 = [r2], 32; \ | ||
714 | ldf.fill.nta f15 = [r3], 32; \ | ||
715 | ;; \ | ||
716 | ldf.fill.nta f16 = [r2], 32; \ | ||
717 | ldf.fill.nta f17 = [r3], 32; \ | ||
718 | ;; \ | ||
719 | ldf.fill.nta f18 = [r2], 32; \ | ||
720 | ldf.fill.nta f19 = [r3], 32; \ | ||
721 | ;; \ | ||
722 | ldf.fill.nta f20 = [r2], 32; \ | ||
723 | ldf.fill.nta f21 = [r3], 32; \ | ||
724 | ;; \ | ||
725 | ldf.fill.nta f22 = [r2], 32; \ | ||
726 | ldf.fill.nta f23 = [r3], 32; \ | ||
727 | ;; \ | ||
728 | ldf.fill.nta f24 = [r2], 32; \ | ||
729 | ldf.fill.nta f25 = [r3], 32; \ | ||
730 | ;; \ | ||
731 | ldf.fill.nta f26 = [r2], 32; \ | ||
732 | ldf.fill.nta f27 = [r3], 32; \ | ||
733 | ;; \ | ||
734 | ldf.fill.nta f28 = [r2], 32; \ | ||
735 | ldf.fill.nta f29 = [r3], 32; \ | ||
736 | ;; \ | ||
737 | ldf.fill.nta f30 = [r2], 32; \ | ||
738 | ldf.fill.nta f31 = [r3], 32; \ | ||
739 | ;; | ||
740 | |||
741 | |||
742 | |||
743 | /* | ||
744 | * r33: point to context_t structure | ||
745 | */ | ||
746 | #define RESTORE_FPU_HIGH \ | ||
747 | add r2 = CTX(F32), r33; \ | ||
748 | add r3 = CTX(F33), r33; \ | ||
749 | ;; \ | ||
750 | ldf.fill.nta f32 = [r2], 32; \ | ||
751 | ldf.fill.nta f33 = [r3], 32; \ | ||
752 | ;; \ | ||
753 | ldf.fill.nta f34 = [r2], 32; \ | ||
754 | ldf.fill.nta f35 = [r3], 32; \ | ||
755 | ;; \ | ||
756 | ldf.fill.nta f36 = [r2], 32; \ | ||
757 | ldf.fill.nta f37 = [r3], 32; \ | ||
758 | ;; \ | ||
759 | ldf.fill.nta f38 = [r2], 32; \ | ||
760 | ldf.fill.nta f39 = [r3], 32; \ | ||
761 | ;; \ | ||
762 | ldf.fill.nta f40 = [r2], 32; \ | ||
763 | ldf.fill.nta f41 = [r3], 32; \ | ||
764 | ;; \ | ||
765 | ldf.fill.nta f42 = [r2], 32; \ | ||
766 | ldf.fill.nta f43 = [r3], 32; \ | ||
767 | ;; \ | ||
768 | ldf.fill.nta f44 = [r2], 32; \ | ||
769 | ldf.fill.nta f45 = [r3], 32; \ | ||
770 | ;; \ | ||
771 | ldf.fill.nta f46 = [r2], 32; \ | ||
772 | ldf.fill.nta f47 = [r3], 32; \ | ||
773 | ;; \ | ||
774 | ldf.fill.nta f48 = [r2], 32; \ | ||
775 | ldf.fill.nta f49 = [r3], 32; \ | ||
776 | ;; \ | ||
777 | ldf.fill.nta f50 = [r2], 32; \ | ||
778 | ldf.fill.nta f51 = [r3], 32; \ | ||
779 | ;; \ | ||
780 | ldf.fill.nta f52 = [r2], 32; \ | ||
781 | ldf.fill.nta f53 = [r3], 32; \ | ||
782 | ;; \ | ||
783 | ldf.fill.nta f54 = [r2], 32; \ | ||
784 | ldf.fill.nta f55 = [r3], 32; \ | ||
785 | ;; \ | ||
786 | ldf.fill.nta f56 = [r2], 32; \ | ||
787 | ldf.fill.nta f57 = [r3], 32; \ | ||
788 | ;; \ | ||
789 | ldf.fill.nta f58 = [r2], 32; \ | ||
790 | ldf.fill.nta f59 = [r3], 32; \ | ||
791 | ;; \ | ||
792 | ldf.fill.nta f60 = [r2], 32; \ | ||
793 | ldf.fill.nta f61 = [r3], 32; \ | ||
794 | ;; \ | ||
795 | ldf.fill.nta f62 = [r2], 32; \ | ||
796 | ldf.fill.nta f63 = [r3], 32; \ | ||
797 | ;; \ | ||
798 | ldf.fill.nta f64 = [r2], 32; \ | ||
799 | ldf.fill.nta f65 = [r3], 32; \ | ||
800 | ;; \ | ||
801 | ldf.fill.nta f66 = [r2], 32; \ | ||
802 | ldf.fill.nta f67 = [r3], 32; \ | ||
803 | ;; \ | ||
804 | ldf.fill.nta f68 = [r2], 32; \ | ||
805 | ldf.fill.nta f69 = [r3], 32; \ | ||
806 | ;; \ | ||
807 | ldf.fill.nta f70 = [r2], 32; \ | ||
808 | ldf.fill.nta f71 = [r3], 32; \ | ||
809 | ;; \ | ||
810 | ldf.fill.nta f72 = [r2], 32; \ | ||
811 | ldf.fill.nta f73 = [r3], 32; \ | ||
812 | ;; \ | ||
813 | ldf.fill.nta f74 = [r2], 32; \ | ||
814 | ldf.fill.nta f75 = [r3], 32; \ | ||
815 | ;; \ | ||
816 | ldf.fill.nta f76 = [r2], 32; \ | ||
817 | ldf.fill.nta f77 = [r3], 32; \ | ||
818 | ;; \ | ||
819 | ldf.fill.nta f78 = [r2], 32; \ | ||
820 | ldf.fill.nta f79 = [r3], 32; \ | ||
821 | ;; \ | ||
822 | ldf.fill.nta f80 = [r2], 32; \ | ||
823 | ldf.fill.nta f81 = [r3], 32; \ | ||
824 | ;; \ | ||
825 | ldf.fill.nta f82 = [r2], 32; \ | ||
826 | ldf.fill.nta f83 = [r3], 32; \ | ||
827 | ;; \ | ||
828 | ldf.fill.nta f84 = [r2], 32; \ | ||
829 | ldf.fill.nta f85 = [r3], 32; \ | ||
830 | ;; \ | ||
831 | ldf.fill.nta f86 = [r2], 32; \ | ||
832 | ldf.fill.nta f87 = [r3], 32; \ | ||
833 | ;; \ | ||
834 | ldf.fill.nta f88 = [r2], 32; \ | ||
835 | ldf.fill.nta f89 = [r3], 32; \ | ||
836 | ;; \ | ||
837 | ldf.fill.nta f90 = [r2], 32; \ | ||
838 | ldf.fill.nta f91 = [r3], 32; \ | ||
839 | ;; \ | ||
840 | ldf.fill.nta f92 = [r2], 32; \ | ||
841 | ldf.fill.nta f93 = [r3], 32; \ | ||
842 | ;; \ | ||
843 | ldf.fill.nta f94 = [r2], 32; \ | ||
844 | ldf.fill.nta f95 = [r3], 32; \ | ||
845 | ;; \ | ||
846 | ldf.fill.nta f96 = [r2], 32; \ | ||
847 | ldf.fill.nta f97 = [r3], 32; \ | ||
848 | ;; \ | ||
849 | ldf.fill.nta f98 = [r2], 32; \ | ||
850 | ldf.fill.nta f99 = [r3], 32; \ | ||
851 | ;; \ | ||
852 | ldf.fill.nta f100 = [r2], 32; \ | ||
853 | ldf.fill.nta f101 = [r3], 32; \ | ||
854 | ;; \ | ||
855 | ldf.fill.nta f102 = [r2], 32; \ | ||
856 | ldf.fill.nta f103 = [r3], 32; \ | ||
857 | ;; \ | ||
858 | ldf.fill.nta f104 = [r2], 32; \ | ||
859 | ldf.fill.nta f105 = [r3], 32; \ | ||
860 | ;; \ | ||
861 | ldf.fill.nta f106 = [r2], 32; \ | ||
862 | ldf.fill.nta f107 = [r3], 32; \ | ||
863 | ;; \ | ||
864 | ldf.fill.nta f108 = [r2], 32; \ | ||
865 | ldf.fill.nta f109 = [r3], 32; \ | ||
866 | ;; \ | ||
867 | ldf.fill.nta f110 = [r2], 32; \ | ||
868 | ldf.fill.nta f111 = [r3], 32; \ | ||
869 | ;; \ | ||
870 | ldf.fill.nta f112 = [r2], 32; \ | ||
871 | ldf.fill.nta f113 = [r3], 32; \ | ||
872 | ;; \ | ||
873 | ldf.fill.nta f114 = [r2], 32; \ | ||
874 | ldf.fill.nta f115 = [r3], 32; \ | ||
875 | ;; \ | ||
876 | ldf.fill.nta f116 = [r2], 32; \ | ||
877 | ldf.fill.nta f117 = [r3], 32; \ | ||
878 | ;; \ | ||
879 | ldf.fill.nta f118 = [r2], 32; \ | ||
880 | ldf.fill.nta f119 = [r3], 32; \ | ||
881 | ;; \ | ||
882 | ldf.fill.nta f120 = [r2], 32; \ | ||
883 | ldf.fill.nta f121 = [r3], 32; \ | ||
884 | ;; \ | ||
885 | ldf.fill.nta f122 = [r2], 32; \ | ||
886 | ldf.fill.nta f123 = [r3], 32; \ | ||
887 | ;; \ | ||
888 | ldf.fill.nta f124 = [r2], 32; \ | ||
889 | ldf.fill.nta f125 = [r3], 32; \ | ||
890 | ;; \ | ||
891 | ldf.fill.nta f126 = [r2], 32; \ | ||
892 | ldf.fill.nta f127 = [r3], 32; \ | ||
893 | ;; | ||
894 | |||
895 | /* | ||
896 | * r32: context_t base address | ||
897 | */ | ||
898 | #define SAVE_PTK_REGS \ | ||
899 | add r2=CTX(PKR0), r32; \ | ||
900 | mov r16=7; \ | ||
901 | ;; \ | ||
902 | mov ar.lc=r16; \ | ||
903 | mov r17=r0; \ | ||
904 | ;; \ | ||
905 | 1: \ | ||
906 | mov r18=pkr[r17]; \ | ||
907 | ;; \ | ||
908 | srlz.i; \ | ||
909 | ;; \ | ||
910 | st8 [r2]=r18, 8; \ | ||
911 | ;; \ | ||
912 | add r17 =1,r17; \ | ||
913 | ;; \ | ||
914 | br.cloop.sptk 1b; \ | ||
915 | ;; | ||
916 | |||
917 | /* | ||
918 | * r33: point to context_t structure | ||
919 | * ar.lc are corrupted. | ||
920 | */ | ||
921 | #define RESTORE_PTK_REGS \ | ||
922 | add r2=CTX(PKR0), r33; \ | ||
923 | mov r16=7; \ | ||
924 | ;; \ | ||
925 | mov ar.lc=r16; \ | ||
926 | mov r17=r0; \ | ||
927 | ;; \ | ||
928 | 1: \ | ||
929 | ld8 r18=[r2], 8; \ | ||
930 | ;; \ | ||
931 | mov pkr[r17]=r18; \ | ||
932 | ;; \ | ||
933 | srlz.i; \ | ||
934 | ;; \ | ||
935 | add r17 =1,r17; \ | ||
936 | ;; \ | ||
937 | br.cloop.sptk 1b; \ | ||
938 | ;; | ||
939 | |||
940 | |||
941 | /* | ||
942 | * void vmm_trampoline( context_t * from, | ||
943 | * context_t * to) | ||
944 | * | ||
945 | * from: r32 | ||
946 | * to: r33 | ||
947 | * note: interrupt disabled before call this function. | ||
948 | */ | ||
949 | GLOBAL_ENTRY(vmm_trampoline) | ||
950 | mov r16 = psr | ||
951 | adds r2 = CTX(PSR), r32 | ||
952 | ;; | ||
953 | st8 [r2] = r16, 8 // psr | ||
954 | mov r17 = pr | ||
955 | ;; | ||
956 | st8 [r2] = r17, 8 // pr | ||
957 | mov r18 = ar.unat | ||
958 | ;; | ||
959 | st8 [r2] = r18 | ||
960 | mov r17 = ar.rsc | ||
961 | ;; | ||
962 | adds r2 = CTX(RSC),r32 | ||
963 | ;; | ||
964 | st8 [r2]= r17 | ||
965 | mov ar.rsc =0 | ||
966 | flushrs | ||
967 | ;; | ||
968 | SAVE_GENERAL_REGS | ||
969 | ;; | ||
970 | SAVE_KERNEL_REGS | ||
971 | ;; | ||
972 | SAVE_APP_REGS | ||
973 | ;; | ||
974 | SAVE_BRANCH_REGS | ||
975 | ;; | ||
976 | SAVE_CTL_REGS | ||
977 | ;; | ||
978 | SAVE_REGION_REGS | ||
979 | ;; | ||
980 | //SAVE_DEBUG_REGS | ||
981 | ;; | ||
982 | rsm psr.dfl | ||
983 | ;; | ||
984 | srlz.d | ||
985 | ;; | ||
986 | SAVE_FPU_LOW | ||
987 | ;; | ||
988 | rsm psr.dfh | ||
989 | ;; | ||
990 | srlz.d | ||
991 | ;; | ||
992 | SAVE_FPU_HIGH | ||
993 | ;; | ||
994 | SAVE_PTK_REGS | ||
995 | ;; | ||
996 | RESTORE_PTK_REGS | ||
997 | ;; | ||
998 | RESTORE_FPU_HIGH | ||
999 | ;; | ||
1000 | RESTORE_FPU_LOW | ||
1001 | ;; | ||
1002 | //RESTORE_DEBUG_REGS | ||
1003 | ;; | ||
1004 | RESTORE_REGION_REGS | ||
1005 | ;; | ||
1006 | RESTORE_CTL_REGS | ||
1007 | ;; | ||
1008 | RESTORE_BRANCH_REGS | ||
1009 | ;; | ||
1010 | RESTORE_APP_REGS | ||
1011 | ;; | ||
1012 | RESTORE_KERNEL_REGS | ||
1013 | ;; | ||
1014 | RESTORE_GENERAL_REGS | ||
1015 | ;; | ||
1016 | adds r2=CTX(PSR), r33 | ||
1017 | ;; | ||
1018 | ld8 r16=[r2], 8 // psr | ||
1019 | ;; | ||
1020 | mov psr.l=r16 | ||
1021 | ;; | ||
1022 | srlz.d | ||
1023 | ;; | ||
1024 | ld8 r16=[r2], 8 // pr | ||
1025 | ;; | ||
1026 | mov pr =r16,-1 | ||
1027 | ld8 r16=[r2] // unat | ||
1028 | ;; | ||
1029 | mov ar.unat=r16 | ||
1030 | ;; | ||
1031 | adds r2=CTX(RSC),r33 | ||
1032 | ;; | ||
1033 | ld8 r16 =[r2] | ||
1034 | ;; | ||
1035 | mov ar.rsc = r16 | ||
1036 | ;; | ||
1037 | br.ret.sptk.few b0 | ||
1038 | END(vmm_trampoline) | ||
diff --git a/arch/ia64/kvm/vcpu.c b/arch/ia64/kvm/vcpu.c deleted file mode 100644 index 958815c9787d..000000000000 --- a/arch/ia64/kvm/vcpu.c +++ /dev/null | |||
@@ -1,2209 +0,0 @@ | |||
1 | /* | ||
2 | * kvm_vcpu.c: handling all virtual cpu related thing. | ||
3 | * Copyright (c) 2005, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | ||
16 | * Place - Suite 330, Boston, MA 02111-1307 USA. | ||
17 | * | ||
18 | * Shaofan Li (Susue Li) <susie.li@intel.com> | ||
19 | * Yaozu Dong (Eddie Dong) (Eddie.dong@intel.com) | ||
20 | * Xuefei Xu (Anthony Xu) (Anthony.xu@intel.com) | ||
21 | * Xiantao Zhang <xiantao.zhang@intel.com> | ||
22 | */ | ||
23 | |||
24 | #include <linux/kvm_host.h> | ||
25 | #include <linux/types.h> | ||
26 | |||
27 | #include <asm/processor.h> | ||
28 | #include <asm/ia64regs.h> | ||
29 | #include <asm/gcc_intrin.h> | ||
30 | #include <asm/kregs.h> | ||
31 | #include <asm/pgtable.h> | ||
32 | #include <asm/tlb.h> | ||
33 | |||
34 | #include "asm-offsets.h" | ||
35 | #include "vcpu.h" | ||
36 | |||
37 | /* | ||
38 | * Special notes: | ||
39 | * - Index by it/dt/rt sequence | ||
40 | * - Only existing mode transitions are allowed in this table | ||
41 | * - RSE is placed at lazy mode when emulating guest partial mode | ||
42 | * - If gva happens to be rr0 and rr4, only allowed case is identity | ||
43 | * mapping (gva=gpa), or panic! (How?) | ||
44 | */ | ||
45 | int mm_switch_table[8][8] = { | ||
46 | /* 2004/09/12(Kevin): Allow switch to self */ | ||
47 | /* | ||
48 | * (it,dt,rt): (0,0,0) -> (1,1,1) | ||
49 | * This kind of transition usually occurs in the very early | ||
50 | * stage of Linux boot up procedure. Another case is in efi | ||
51 | * and pal calls. (see "arch/ia64/kernel/head.S") | ||
52 | * | ||
53 | * (it,dt,rt): (0,0,0) -> (0,1,1) | ||
54 | * This kind of transition is found when OSYa exits efi boot | ||
55 | * service. Due to gva = gpa in this case (Same region), | ||
56 | * data access can be satisfied though itlb entry for physical | ||
57 | * emulation is hit. | ||
58 | */ | ||
59 | {SW_SELF, 0, 0, SW_NOP, 0, 0, 0, SW_P2V}, | ||
60 | {0, 0, 0, 0, 0, 0, 0, 0}, | ||
61 | {0, 0, 0, 0, 0, 0, 0, 0}, | ||
62 | /* | ||
63 | * (it,dt,rt): (0,1,1) -> (1,1,1) | ||
64 | * This kind of transition is found in OSYa. | ||
65 | * | ||
66 | * (it,dt,rt): (0,1,1) -> (0,0,0) | ||
67 | * This kind of transition is found in OSYa | ||
68 | */ | ||
69 | {SW_NOP, 0, 0, SW_SELF, 0, 0, 0, SW_P2V}, | ||
70 | /* (1,0,0)->(1,1,1) */ | ||
71 | {0, 0, 0, 0, 0, 0, 0, SW_P2V}, | ||
72 | /* | ||
73 | * (it,dt,rt): (1,0,1) -> (1,1,1) | ||
74 | * This kind of transition usually occurs when Linux returns | ||
75 | * from the low level TLB miss handlers. | ||
76 | * (see "arch/ia64/kernel/ivt.S") | ||
77 | */ | ||
78 | {0, 0, 0, 0, 0, SW_SELF, 0, SW_P2V}, | ||
79 | {0, 0, 0, 0, 0, 0, 0, 0}, | ||
80 | /* | ||
81 | * (it,dt,rt): (1,1,1) -> (1,0,1) | ||
82 | * This kind of transition usually occurs in Linux low level | ||
83 | * TLB miss handler. (see "arch/ia64/kernel/ivt.S") | ||
84 | * | ||
85 | * (it,dt,rt): (1,1,1) -> (0,0,0) | ||
86 | * This kind of transition usually occurs in pal and efi calls, | ||
87 | * which requires running in physical mode. | ||
88 | * (see "arch/ia64/kernel/head.S") | ||
89 | * (1,1,1)->(1,0,0) | ||
90 | */ | ||
91 | |||
92 | {SW_V2P, 0, 0, 0, SW_V2P, SW_V2P, 0, SW_SELF}, | ||
93 | }; | ||
94 | |||
95 | void physical_mode_init(struct kvm_vcpu *vcpu) | ||
96 | { | ||
97 | vcpu->arch.mode_flags = GUEST_IN_PHY; | ||
98 | } | ||
99 | |||
100 | void switch_to_physical_rid(struct kvm_vcpu *vcpu) | ||
101 | { | ||
102 | unsigned long psr; | ||
103 | |||
104 | /* Save original virtual mode rr[0] and rr[4] */ | ||
105 | psr = ia64_clear_ic(); | ||
106 | ia64_set_rr(VRN0<<VRN_SHIFT, vcpu->arch.metaphysical_rr0); | ||
107 | ia64_srlz_d(); | ||
108 | ia64_set_rr(VRN4<<VRN_SHIFT, vcpu->arch.metaphysical_rr4); | ||
109 | ia64_srlz_d(); | ||
110 | |||
111 | ia64_set_psr(psr); | ||
112 | return; | ||
113 | } | ||
114 | |||
115 | void switch_to_virtual_rid(struct kvm_vcpu *vcpu) | ||
116 | { | ||
117 | unsigned long psr; | ||
118 | |||
119 | psr = ia64_clear_ic(); | ||
120 | ia64_set_rr(VRN0 << VRN_SHIFT, vcpu->arch.metaphysical_saved_rr0); | ||
121 | ia64_srlz_d(); | ||
122 | ia64_set_rr(VRN4 << VRN_SHIFT, vcpu->arch.metaphysical_saved_rr4); | ||
123 | ia64_srlz_d(); | ||
124 | ia64_set_psr(psr); | ||
125 | return; | ||
126 | } | ||
127 | |||
128 | static int mm_switch_action(struct ia64_psr opsr, struct ia64_psr npsr) | ||
129 | { | ||
130 | return mm_switch_table[MODE_IND(opsr)][MODE_IND(npsr)]; | ||
131 | } | ||
132 | |||
133 | void switch_mm_mode(struct kvm_vcpu *vcpu, struct ia64_psr old_psr, | ||
134 | struct ia64_psr new_psr) | ||
135 | { | ||
136 | int act; | ||
137 | act = mm_switch_action(old_psr, new_psr); | ||
138 | switch (act) { | ||
139 | case SW_V2P: | ||
140 | /*printk("V -> P mode transition: (0x%lx -> 0x%lx)\n", | ||
141 | old_psr.val, new_psr.val);*/ | ||
142 | switch_to_physical_rid(vcpu); | ||
143 | /* | ||
144 | * Set rse to enforced lazy, to prevent active rse | ||
145 | *save/restor when guest physical mode. | ||
146 | */ | ||
147 | vcpu->arch.mode_flags |= GUEST_IN_PHY; | ||
148 | break; | ||
149 | case SW_P2V: | ||
150 | switch_to_virtual_rid(vcpu); | ||
151 | /* | ||
152 | * recover old mode which is saved when entering | ||
153 | * guest physical mode | ||
154 | */ | ||
155 | vcpu->arch.mode_flags &= ~GUEST_IN_PHY; | ||
156 | break; | ||
157 | case SW_SELF: | ||
158 | break; | ||
159 | case SW_NOP: | ||
160 | break; | ||
161 | default: | ||
162 | /* Sanity check */ | ||
163 | break; | ||
164 | } | ||
165 | return; | ||
166 | } | ||
167 | |||
168 | /* | ||
169 | * In physical mode, insert tc/tr for region 0 and 4 uses | ||
170 | * RID[0] and RID[4] which is for physical mode emulation. | ||
171 | * However what those inserted tc/tr wants is rid for | ||
172 | * virtual mode. So original virtual rid needs to be restored | ||
173 | * before insert. | ||
174 | * | ||
175 | * Operations which required such switch include: | ||
176 | * - insertions (itc.*, itr.*) | ||
177 | * - purges (ptc.* and ptr.*) | ||
178 | * - tpa | ||
179 | * - tak | ||
180 | * - thash?, ttag? | ||
181 | * All above needs actual virtual rid for destination entry. | ||
182 | */ | ||
183 | |||
184 | void check_mm_mode_switch(struct kvm_vcpu *vcpu, struct ia64_psr old_psr, | ||
185 | struct ia64_psr new_psr) | ||
186 | { | ||
187 | |||
188 | if ((old_psr.dt != new_psr.dt) | ||
189 | || (old_psr.it != new_psr.it) | ||
190 | || (old_psr.rt != new_psr.rt)) | ||
191 | switch_mm_mode(vcpu, old_psr, new_psr); | ||
192 | |||
193 | return; | ||
194 | } | ||
195 | |||
196 | |||
197 | /* | ||
198 | * In physical mode, insert tc/tr for region 0 and 4 uses | ||
199 | * RID[0] and RID[4] which is for physical mode emulation. | ||
200 | * However what those inserted tc/tr wants is rid for | ||
201 | * virtual mode. So original virtual rid needs to be restored | ||
202 | * before insert. | ||
203 | * | ||
204 | * Operations which required such switch include: | ||
205 | * - insertions (itc.*, itr.*) | ||
206 | * - purges (ptc.* and ptr.*) | ||
207 | * - tpa | ||
208 | * - tak | ||
209 | * - thash?, ttag? | ||
210 | * All above needs actual virtual rid for destination entry. | ||
211 | */ | ||
212 | |||
213 | void prepare_if_physical_mode(struct kvm_vcpu *vcpu) | ||
214 | { | ||
215 | if (is_physical_mode(vcpu)) { | ||
216 | vcpu->arch.mode_flags |= GUEST_PHY_EMUL; | ||
217 | switch_to_virtual_rid(vcpu); | ||
218 | } | ||
219 | return; | ||
220 | } | ||
221 | |||
222 | /* Recover always follows prepare */ | ||
223 | void recover_if_physical_mode(struct kvm_vcpu *vcpu) | ||
224 | { | ||
225 | if (is_physical_mode(vcpu)) | ||
226 | switch_to_physical_rid(vcpu); | ||
227 | vcpu->arch.mode_flags &= ~GUEST_PHY_EMUL; | ||
228 | return; | ||
229 | } | ||
230 | |||
231 | #define RPT(x) ((u16) &((struct kvm_pt_regs *)0)->x) | ||
232 | |||
233 | static u16 gr_info[32] = { | ||
234 | 0, /* r0 is read-only : WE SHOULD NEVER GET THIS */ | ||
235 | RPT(r1), RPT(r2), RPT(r3), | ||
236 | RPT(r4), RPT(r5), RPT(r6), RPT(r7), | ||
237 | RPT(r8), RPT(r9), RPT(r10), RPT(r11), | ||
238 | RPT(r12), RPT(r13), RPT(r14), RPT(r15), | ||
239 | RPT(r16), RPT(r17), RPT(r18), RPT(r19), | ||
240 | RPT(r20), RPT(r21), RPT(r22), RPT(r23), | ||
241 | RPT(r24), RPT(r25), RPT(r26), RPT(r27), | ||
242 | RPT(r28), RPT(r29), RPT(r30), RPT(r31) | ||
243 | }; | ||
244 | |||
245 | #define IA64_FIRST_STACKED_GR 32 | ||
246 | #define IA64_FIRST_ROTATING_FR 32 | ||
247 | |||
248 | static inline unsigned long | ||
249 | rotate_reg(unsigned long sor, unsigned long rrb, unsigned long reg) | ||
250 | { | ||
251 | reg += rrb; | ||
252 | if (reg >= sor) | ||
253 | reg -= sor; | ||
254 | return reg; | ||
255 | } | ||
256 | |||
257 | /* | ||
258 | * Return the (rotated) index for floating point register | ||
259 | * be in the REGNUM (REGNUM must range from 32-127, | ||
260 | * result is in the range from 0-95. | ||
261 | */ | ||
262 | static inline unsigned long fph_index(struct kvm_pt_regs *regs, | ||
263 | long regnum) | ||
264 | { | ||
265 | unsigned long rrb_fr = (regs->cr_ifs >> 25) & 0x7f; | ||
266 | return rotate_reg(96, rrb_fr, (regnum - IA64_FIRST_ROTATING_FR)); | ||
267 | } | ||
268 | |||
269 | /* | ||
270 | * The inverse of the above: given bspstore and the number of | ||
271 | * registers, calculate ar.bsp. | ||
272 | */ | ||
273 | static inline unsigned long *kvm_rse_skip_regs(unsigned long *addr, | ||
274 | long num_regs) | ||
275 | { | ||
276 | long delta = ia64_rse_slot_num(addr) + num_regs; | ||
277 | int i = 0; | ||
278 | |||
279 | if (num_regs < 0) | ||
280 | delta -= 0x3e; | ||
281 | if (delta < 0) { | ||
282 | while (delta <= -0x3f) { | ||
283 | i--; | ||
284 | delta += 0x3f; | ||
285 | } | ||
286 | } else { | ||
287 | while (delta >= 0x3f) { | ||
288 | i++; | ||
289 | delta -= 0x3f; | ||
290 | } | ||
291 | } | ||
292 | |||
293 | return addr + num_regs + i; | ||
294 | } | ||
295 | |||
296 | static void get_rse_reg(struct kvm_pt_regs *regs, unsigned long r1, | ||
297 | unsigned long *val, int *nat) | ||
298 | { | ||
299 | unsigned long *bsp, *addr, *rnat_addr, *bspstore; | ||
300 | unsigned long *kbs = (void *) current_vcpu + VMM_RBS_OFFSET; | ||
301 | unsigned long nat_mask; | ||
302 | unsigned long old_rsc, new_rsc; | ||
303 | long sof = (regs->cr_ifs) & 0x7f; | ||
304 | long sor = (((regs->cr_ifs >> 14) & 0xf) << 3); | ||
305 | long rrb_gr = (regs->cr_ifs >> 18) & 0x7f; | ||
306 | long ridx = r1 - 32; | ||
307 | |||
308 | if (ridx < sor) | ||
309 | ridx = rotate_reg(sor, rrb_gr, ridx); | ||
310 | |||
311 | old_rsc = ia64_getreg(_IA64_REG_AR_RSC); | ||
312 | new_rsc = old_rsc&(~(0x3)); | ||
313 | ia64_setreg(_IA64_REG_AR_RSC, new_rsc); | ||
314 | |||
315 | bspstore = (unsigned long *)ia64_getreg(_IA64_REG_AR_BSPSTORE); | ||
316 | bsp = kbs + (regs->loadrs >> 19); | ||
317 | |||
318 | addr = kvm_rse_skip_regs(bsp, -sof + ridx); | ||
319 | nat_mask = 1UL << ia64_rse_slot_num(addr); | ||
320 | rnat_addr = ia64_rse_rnat_addr(addr); | ||
321 | |||
322 | if (addr >= bspstore) { | ||
323 | ia64_flushrs(); | ||
324 | ia64_mf(); | ||
325 | bspstore = (unsigned long *)ia64_getreg(_IA64_REG_AR_BSPSTORE); | ||
326 | } | ||
327 | *val = *addr; | ||
328 | if (nat) { | ||
329 | if (bspstore < rnat_addr) | ||
330 | *nat = (int)!!(ia64_getreg(_IA64_REG_AR_RNAT) | ||
331 | & nat_mask); | ||
332 | else | ||
333 | *nat = (int)!!((*rnat_addr) & nat_mask); | ||
334 | ia64_setreg(_IA64_REG_AR_RSC, old_rsc); | ||
335 | } | ||
336 | } | ||
337 | |||
338 | void set_rse_reg(struct kvm_pt_regs *regs, unsigned long r1, | ||
339 | unsigned long val, unsigned long nat) | ||
340 | { | ||
341 | unsigned long *bsp, *bspstore, *addr, *rnat_addr; | ||
342 | unsigned long *kbs = (void *) current_vcpu + VMM_RBS_OFFSET; | ||
343 | unsigned long nat_mask; | ||
344 | unsigned long old_rsc, new_rsc, psr; | ||
345 | unsigned long rnat; | ||
346 | long sof = (regs->cr_ifs) & 0x7f; | ||
347 | long sor = (((regs->cr_ifs >> 14) & 0xf) << 3); | ||
348 | long rrb_gr = (regs->cr_ifs >> 18) & 0x7f; | ||
349 | long ridx = r1 - 32; | ||
350 | |||
351 | if (ridx < sor) | ||
352 | ridx = rotate_reg(sor, rrb_gr, ridx); | ||
353 | |||
354 | old_rsc = ia64_getreg(_IA64_REG_AR_RSC); | ||
355 | /* put RSC to lazy mode, and set loadrs 0 */ | ||
356 | new_rsc = old_rsc & (~0x3fff0003); | ||
357 | ia64_setreg(_IA64_REG_AR_RSC, new_rsc); | ||
358 | bsp = kbs + (regs->loadrs >> 19); /* 16 + 3 */ | ||
359 | |||
360 | addr = kvm_rse_skip_regs(bsp, -sof + ridx); | ||
361 | nat_mask = 1UL << ia64_rse_slot_num(addr); | ||
362 | rnat_addr = ia64_rse_rnat_addr(addr); | ||
363 | |||
364 | local_irq_save(psr); | ||
365 | bspstore = (unsigned long *)ia64_getreg(_IA64_REG_AR_BSPSTORE); | ||
366 | if (addr >= bspstore) { | ||
367 | |||
368 | ia64_flushrs(); | ||
369 | ia64_mf(); | ||
370 | *addr = val; | ||
371 | bspstore = (unsigned long *)ia64_getreg(_IA64_REG_AR_BSPSTORE); | ||
372 | rnat = ia64_getreg(_IA64_REG_AR_RNAT); | ||
373 | if (bspstore < rnat_addr) | ||
374 | rnat = rnat & (~nat_mask); | ||
375 | else | ||
376 | *rnat_addr = (*rnat_addr)&(~nat_mask); | ||
377 | |||
378 | ia64_mf(); | ||
379 | ia64_loadrs(); | ||
380 | ia64_setreg(_IA64_REG_AR_RNAT, rnat); | ||
381 | } else { | ||
382 | rnat = ia64_getreg(_IA64_REG_AR_RNAT); | ||
383 | *addr = val; | ||
384 | if (bspstore < rnat_addr) | ||
385 | rnat = rnat&(~nat_mask); | ||
386 | else | ||
387 | *rnat_addr = (*rnat_addr) & (~nat_mask); | ||
388 | |||
389 | ia64_setreg(_IA64_REG_AR_BSPSTORE, (unsigned long)bspstore); | ||
390 | ia64_setreg(_IA64_REG_AR_RNAT, rnat); | ||
391 | } | ||
392 | local_irq_restore(psr); | ||
393 | ia64_setreg(_IA64_REG_AR_RSC, old_rsc); | ||
394 | } | ||
395 | |||
396 | void getreg(unsigned long regnum, unsigned long *val, | ||
397 | int *nat, struct kvm_pt_regs *regs) | ||
398 | { | ||
399 | unsigned long addr, *unat; | ||
400 | if (regnum >= IA64_FIRST_STACKED_GR) { | ||
401 | get_rse_reg(regs, regnum, val, nat); | ||
402 | return; | ||
403 | } | ||
404 | |||
405 | /* | ||
406 | * Now look at registers in [0-31] range and init correct UNAT | ||
407 | */ | ||
408 | addr = (unsigned long)regs; | ||
409 | unat = ®s->eml_unat; | ||
410 | |||
411 | addr += gr_info[regnum]; | ||
412 | |||
413 | *val = *(unsigned long *)addr; | ||
414 | /* | ||
415 | * do it only when requested | ||
416 | */ | ||
417 | if (nat) | ||
418 | *nat = (*unat >> ((addr >> 3) & 0x3f)) & 0x1UL; | ||
419 | } | ||
420 | |||
421 | void setreg(unsigned long regnum, unsigned long val, | ||
422 | int nat, struct kvm_pt_regs *regs) | ||
423 | { | ||
424 | unsigned long addr; | ||
425 | unsigned long bitmask; | ||
426 | unsigned long *unat; | ||
427 | |||
428 | /* | ||
429 | * First takes care of stacked registers | ||
430 | */ | ||
431 | if (regnum >= IA64_FIRST_STACKED_GR) { | ||
432 | set_rse_reg(regs, regnum, val, nat); | ||
433 | return; | ||
434 | } | ||
435 | |||
436 | /* | ||
437 | * Now look at registers in [0-31] range and init correct UNAT | ||
438 | */ | ||
439 | addr = (unsigned long)regs; | ||
440 | unat = ®s->eml_unat; | ||
441 | /* | ||
442 | * add offset from base of struct | ||
443 | * and do it ! | ||
444 | */ | ||
445 | addr += gr_info[regnum]; | ||
446 | |||
447 | *(unsigned long *)addr = val; | ||
448 | |||
449 | /* | ||
450 | * We need to clear the corresponding UNAT bit to fully emulate the load | ||
451 | * UNAT bit_pos = GR[r3]{8:3} form EAS-2.4 | ||
452 | */ | ||
453 | bitmask = 1UL << ((addr >> 3) & 0x3f); | ||
454 | if (nat) | ||
455 | *unat |= bitmask; | ||
456 | else | ||
457 | *unat &= ~bitmask; | ||
458 | |||
459 | } | ||
460 | |||
461 | u64 vcpu_get_gr(struct kvm_vcpu *vcpu, unsigned long reg) | ||
462 | { | ||
463 | struct kvm_pt_regs *regs = vcpu_regs(vcpu); | ||
464 | unsigned long val; | ||
465 | |||
466 | if (!reg) | ||
467 | return 0; | ||
468 | getreg(reg, &val, 0, regs); | ||
469 | return val; | ||
470 | } | ||
471 | |||
472 | void vcpu_set_gr(struct kvm_vcpu *vcpu, unsigned long reg, u64 value, int nat) | ||
473 | { | ||
474 | struct kvm_pt_regs *regs = vcpu_regs(vcpu); | ||
475 | long sof = (regs->cr_ifs) & 0x7f; | ||
476 | |||
477 | if (!reg) | ||
478 | return; | ||
479 | if (reg >= sof + 32) | ||
480 | return; | ||
481 | setreg(reg, value, nat, regs); /* FIXME: handle NATs later*/ | ||
482 | } | ||
483 | |||
484 | void getfpreg(unsigned long regnum, struct ia64_fpreg *fpval, | ||
485 | struct kvm_pt_regs *regs) | ||
486 | { | ||
487 | /* Take floating register rotation into consideration*/ | ||
488 | if (regnum >= IA64_FIRST_ROTATING_FR) | ||
489 | regnum = IA64_FIRST_ROTATING_FR + fph_index(regs, regnum); | ||
490 | #define CASE_FIXED_FP(reg) \ | ||
491 | case (reg) : \ | ||
492 | ia64_stf_spill(fpval, reg); \ | ||
493 | break | ||
494 | |||
495 | switch (regnum) { | ||
496 | CASE_FIXED_FP(0); | ||
497 | CASE_FIXED_FP(1); | ||
498 | CASE_FIXED_FP(2); | ||
499 | CASE_FIXED_FP(3); | ||
500 | CASE_FIXED_FP(4); | ||
501 | CASE_FIXED_FP(5); | ||
502 | |||
503 | CASE_FIXED_FP(6); | ||
504 | CASE_FIXED_FP(7); | ||
505 | CASE_FIXED_FP(8); | ||
506 | CASE_FIXED_FP(9); | ||
507 | CASE_FIXED_FP(10); | ||
508 | CASE_FIXED_FP(11); | ||
509 | |||
510 | CASE_FIXED_FP(12); | ||
511 | CASE_FIXED_FP(13); | ||
512 | CASE_FIXED_FP(14); | ||
513 | CASE_FIXED_FP(15); | ||
514 | CASE_FIXED_FP(16); | ||
515 | CASE_FIXED_FP(17); | ||
516 | CASE_FIXED_FP(18); | ||
517 | CASE_FIXED_FP(19); | ||
518 | CASE_FIXED_FP(20); | ||
519 | CASE_FIXED_FP(21); | ||
520 | CASE_FIXED_FP(22); | ||
521 | CASE_FIXED_FP(23); | ||
522 | CASE_FIXED_FP(24); | ||
523 | CASE_FIXED_FP(25); | ||
524 | CASE_FIXED_FP(26); | ||
525 | CASE_FIXED_FP(27); | ||
526 | CASE_FIXED_FP(28); | ||
527 | CASE_FIXED_FP(29); | ||
528 | CASE_FIXED_FP(30); | ||
529 | CASE_FIXED_FP(31); | ||
530 | CASE_FIXED_FP(32); | ||
531 | CASE_FIXED_FP(33); | ||
532 | CASE_FIXED_FP(34); | ||
533 | CASE_FIXED_FP(35); | ||
534 | CASE_FIXED_FP(36); | ||
535 | CASE_FIXED_FP(37); | ||
536 | CASE_FIXED_FP(38); | ||
537 | CASE_FIXED_FP(39); | ||
538 | CASE_FIXED_FP(40); | ||
539 | CASE_FIXED_FP(41); | ||
540 | CASE_FIXED_FP(42); | ||
541 | CASE_FIXED_FP(43); | ||
542 | CASE_FIXED_FP(44); | ||
543 | CASE_FIXED_FP(45); | ||
544 | CASE_FIXED_FP(46); | ||
545 | CASE_FIXED_FP(47); | ||
546 | CASE_FIXED_FP(48); | ||
547 | CASE_FIXED_FP(49); | ||
548 | CASE_FIXED_FP(50); | ||
549 | CASE_FIXED_FP(51); | ||
550 | CASE_FIXED_FP(52); | ||
551 | CASE_FIXED_FP(53); | ||
552 | CASE_FIXED_FP(54); | ||
553 | CASE_FIXED_FP(55); | ||
554 | CASE_FIXED_FP(56); | ||
555 | CASE_FIXED_FP(57); | ||
556 | CASE_FIXED_FP(58); | ||
557 | CASE_FIXED_FP(59); | ||
558 | CASE_FIXED_FP(60); | ||
559 | CASE_FIXED_FP(61); | ||
560 | CASE_FIXED_FP(62); | ||
561 | CASE_FIXED_FP(63); | ||
562 | CASE_FIXED_FP(64); | ||
563 | CASE_FIXED_FP(65); | ||
564 | CASE_FIXED_FP(66); | ||
565 | CASE_FIXED_FP(67); | ||
566 | CASE_FIXED_FP(68); | ||
567 | CASE_FIXED_FP(69); | ||
568 | CASE_FIXED_FP(70); | ||
569 | CASE_FIXED_FP(71); | ||
570 | CASE_FIXED_FP(72); | ||
571 | CASE_FIXED_FP(73); | ||
572 | CASE_FIXED_FP(74); | ||
573 | CASE_FIXED_FP(75); | ||
574 | CASE_FIXED_FP(76); | ||
575 | CASE_FIXED_FP(77); | ||
576 | CASE_FIXED_FP(78); | ||
577 | CASE_FIXED_FP(79); | ||
578 | CASE_FIXED_FP(80); | ||
579 | CASE_FIXED_FP(81); | ||
580 | CASE_FIXED_FP(82); | ||
581 | CASE_FIXED_FP(83); | ||
582 | CASE_FIXED_FP(84); | ||
583 | CASE_FIXED_FP(85); | ||
584 | CASE_FIXED_FP(86); | ||
585 | CASE_FIXED_FP(87); | ||
586 | CASE_FIXED_FP(88); | ||
587 | CASE_FIXED_FP(89); | ||
588 | CASE_FIXED_FP(90); | ||
589 | CASE_FIXED_FP(91); | ||
590 | CASE_FIXED_FP(92); | ||
591 | CASE_FIXED_FP(93); | ||
592 | CASE_FIXED_FP(94); | ||
593 | CASE_FIXED_FP(95); | ||
594 | CASE_FIXED_FP(96); | ||
595 | CASE_FIXED_FP(97); | ||
596 | CASE_FIXED_FP(98); | ||
597 | CASE_FIXED_FP(99); | ||
598 | CASE_FIXED_FP(100); | ||
599 | CASE_FIXED_FP(101); | ||
600 | CASE_FIXED_FP(102); | ||
601 | CASE_FIXED_FP(103); | ||
602 | CASE_FIXED_FP(104); | ||
603 | CASE_FIXED_FP(105); | ||
604 | CASE_FIXED_FP(106); | ||
605 | CASE_FIXED_FP(107); | ||
606 | CASE_FIXED_FP(108); | ||
607 | CASE_FIXED_FP(109); | ||
608 | CASE_FIXED_FP(110); | ||
609 | CASE_FIXED_FP(111); | ||
610 | CASE_FIXED_FP(112); | ||
611 | CASE_FIXED_FP(113); | ||
612 | CASE_FIXED_FP(114); | ||
613 | CASE_FIXED_FP(115); | ||
614 | CASE_FIXED_FP(116); | ||
615 | CASE_FIXED_FP(117); | ||
616 | CASE_FIXED_FP(118); | ||
617 | CASE_FIXED_FP(119); | ||
618 | CASE_FIXED_FP(120); | ||
619 | CASE_FIXED_FP(121); | ||
620 | CASE_FIXED_FP(122); | ||
621 | CASE_FIXED_FP(123); | ||
622 | CASE_FIXED_FP(124); | ||
623 | CASE_FIXED_FP(125); | ||
624 | CASE_FIXED_FP(126); | ||
625 | CASE_FIXED_FP(127); | ||
626 | } | ||
627 | #undef CASE_FIXED_FP | ||
628 | } | ||
629 | |||
630 | void setfpreg(unsigned long regnum, struct ia64_fpreg *fpval, | ||
631 | struct kvm_pt_regs *regs) | ||
632 | { | ||
633 | /* Take floating register rotation into consideration*/ | ||
634 | if (regnum >= IA64_FIRST_ROTATING_FR) | ||
635 | regnum = IA64_FIRST_ROTATING_FR + fph_index(regs, regnum); | ||
636 | |||
637 | #define CASE_FIXED_FP(reg) \ | ||
638 | case (reg) : \ | ||
639 | ia64_ldf_fill(reg, fpval); \ | ||
640 | break | ||
641 | |||
642 | switch (regnum) { | ||
643 | CASE_FIXED_FP(2); | ||
644 | CASE_FIXED_FP(3); | ||
645 | CASE_FIXED_FP(4); | ||
646 | CASE_FIXED_FP(5); | ||
647 | |||
648 | CASE_FIXED_FP(6); | ||
649 | CASE_FIXED_FP(7); | ||
650 | CASE_FIXED_FP(8); | ||
651 | CASE_FIXED_FP(9); | ||
652 | CASE_FIXED_FP(10); | ||
653 | CASE_FIXED_FP(11); | ||
654 | |||
655 | CASE_FIXED_FP(12); | ||
656 | CASE_FIXED_FP(13); | ||
657 | CASE_FIXED_FP(14); | ||
658 | CASE_FIXED_FP(15); | ||
659 | CASE_FIXED_FP(16); | ||
660 | CASE_FIXED_FP(17); | ||
661 | CASE_FIXED_FP(18); | ||
662 | CASE_FIXED_FP(19); | ||
663 | CASE_FIXED_FP(20); | ||
664 | CASE_FIXED_FP(21); | ||
665 | CASE_FIXED_FP(22); | ||
666 | CASE_FIXED_FP(23); | ||
667 | CASE_FIXED_FP(24); | ||
668 | CASE_FIXED_FP(25); | ||
669 | CASE_FIXED_FP(26); | ||
670 | CASE_FIXED_FP(27); | ||
671 | CASE_FIXED_FP(28); | ||
672 | CASE_FIXED_FP(29); | ||
673 | CASE_FIXED_FP(30); | ||
674 | CASE_FIXED_FP(31); | ||
675 | CASE_FIXED_FP(32); | ||
676 | CASE_FIXED_FP(33); | ||
677 | CASE_FIXED_FP(34); | ||
678 | CASE_FIXED_FP(35); | ||
679 | CASE_FIXED_FP(36); | ||
680 | CASE_FIXED_FP(37); | ||
681 | CASE_FIXED_FP(38); | ||
682 | CASE_FIXED_FP(39); | ||
683 | CASE_FIXED_FP(40); | ||
684 | CASE_FIXED_FP(41); | ||
685 | CASE_FIXED_FP(42); | ||
686 | CASE_FIXED_FP(43); | ||
687 | CASE_FIXED_FP(44); | ||
688 | CASE_FIXED_FP(45); | ||
689 | CASE_FIXED_FP(46); | ||
690 | CASE_FIXED_FP(47); | ||
691 | CASE_FIXED_FP(48); | ||
692 | CASE_FIXED_FP(49); | ||
693 | CASE_FIXED_FP(50); | ||
694 | CASE_FIXED_FP(51); | ||
695 | CASE_FIXED_FP(52); | ||
696 | CASE_FIXED_FP(53); | ||
697 | CASE_FIXED_FP(54); | ||
698 | CASE_FIXED_FP(55); | ||
699 | CASE_FIXED_FP(56); | ||
700 | CASE_FIXED_FP(57); | ||
701 | CASE_FIXED_FP(58); | ||
702 | CASE_FIXED_FP(59); | ||
703 | CASE_FIXED_FP(60); | ||
704 | CASE_FIXED_FP(61); | ||
705 | CASE_FIXED_FP(62); | ||
706 | CASE_FIXED_FP(63); | ||
707 | CASE_FIXED_FP(64); | ||
708 | CASE_FIXED_FP(65); | ||
709 | CASE_FIXED_FP(66); | ||
710 | CASE_FIXED_FP(67); | ||
711 | CASE_FIXED_FP(68); | ||
712 | CASE_FIXED_FP(69); | ||
713 | CASE_FIXED_FP(70); | ||
714 | CASE_FIXED_FP(71); | ||
715 | CASE_FIXED_FP(72); | ||
716 | CASE_FIXED_FP(73); | ||
717 | CASE_FIXED_FP(74); | ||
718 | CASE_FIXED_FP(75); | ||
719 | CASE_FIXED_FP(76); | ||
720 | CASE_FIXED_FP(77); | ||
721 | CASE_FIXED_FP(78); | ||
722 | CASE_FIXED_FP(79); | ||
723 | CASE_FIXED_FP(80); | ||
724 | CASE_FIXED_FP(81); | ||
725 | CASE_FIXED_FP(82); | ||
726 | CASE_FIXED_FP(83); | ||
727 | CASE_FIXED_FP(84); | ||
728 | CASE_FIXED_FP(85); | ||
729 | CASE_FIXED_FP(86); | ||
730 | CASE_FIXED_FP(87); | ||
731 | CASE_FIXED_FP(88); | ||
732 | CASE_FIXED_FP(89); | ||
733 | CASE_FIXED_FP(90); | ||
734 | CASE_FIXED_FP(91); | ||
735 | CASE_FIXED_FP(92); | ||
736 | CASE_FIXED_FP(93); | ||
737 | CASE_FIXED_FP(94); | ||
738 | CASE_FIXED_FP(95); | ||
739 | CASE_FIXED_FP(96); | ||
740 | CASE_FIXED_FP(97); | ||
741 | CASE_FIXED_FP(98); | ||
742 | CASE_FIXED_FP(99); | ||
743 | CASE_FIXED_FP(100); | ||
744 | CASE_FIXED_FP(101); | ||
745 | CASE_FIXED_FP(102); | ||
746 | CASE_FIXED_FP(103); | ||
747 | CASE_FIXED_FP(104); | ||
748 | CASE_FIXED_FP(105); | ||
749 | CASE_FIXED_FP(106); | ||
750 | CASE_FIXED_FP(107); | ||
751 | CASE_FIXED_FP(108); | ||
752 | CASE_FIXED_FP(109); | ||
753 | CASE_FIXED_FP(110); | ||
754 | CASE_FIXED_FP(111); | ||
755 | CASE_FIXED_FP(112); | ||
756 | CASE_FIXED_FP(113); | ||
757 | CASE_FIXED_FP(114); | ||
758 | CASE_FIXED_FP(115); | ||
759 | CASE_FIXED_FP(116); | ||
760 | CASE_FIXED_FP(117); | ||
761 | CASE_FIXED_FP(118); | ||
762 | CASE_FIXED_FP(119); | ||
763 | CASE_FIXED_FP(120); | ||
764 | CASE_FIXED_FP(121); | ||
765 | CASE_FIXED_FP(122); | ||
766 | CASE_FIXED_FP(123); | ||
767 | CASE_FIXED_FP(124); | ||
768 | CASE_FIXED_FP(125); | ||
769 | CASE_FIXED_FP(126); | ||
770 | CASE_FIXED_FP(127); | ||
771 | } | ||
772 | } | ||
773 | |||
774 | void vcpu_get_fpreg(struct kvm_vcpu *vcpu, unsigned long reg, | ||
775 | struct ia64_fpreg *val) | ||
776 | { | ||
777 | struct kvm_pt_regs *regs = vcpu_regs(vcpu); | ||
778 | |||
779 | getfpreg(reg, val, regs); /* FIXME: handle NATs later*/ | ||
780 | } | ||
781 | |||
782 | void vcpu_set_fpreg(struct kvm_vcpu *vcpu, unsigned long reg, | ||
783 | struct ia64_fpreg *val) | ||
784 | { | ||
785 | struct kvm_pt_regs *regs = vcpu_regs(vcpu); | ||
786 | |||
787 | if (reg > 1) | ||
788 | setfpreg(reg, val, regs); /* FIXME: handle NATs later*/ | ||
789 | } | ||
790 | |||
791 | /* | ||
792 | * The Altix RTC is mapped specially here for the vmm module | ||
793 | */ | ||
794 | #define SN_RTC_BASE (u64 *)(KVM_VMM_BASE+(1UL<<KVM_VMM_SHIFT)) | ||
795 | static long kvm_get_itc(struct kvm_vcpu *vcpu) | ||
796 | { | ||
797 | #if defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC) | ||
798 | struct kvm *kvm = (struct kvm *)KVM_VM_BASE; | ||
799 | |||
800 | if (kvm->arch.is_sn2) | ||
801 | return (*SN_RTC_BASE); | ||
802 | else | ||
803 | #endif | ||
804 | return ia64_getreg(_IA64_REG_AR_ITC); | ||
805 | } | ||
806 | |||
807 | /************************************************************************ | ||
808 | * lsapic timer | ||
809 | ***********************************************************************/ | ||
810 | u64 vcpu_get_itc(struct kvm_vcpu *vcpu) | ||
811 | { | ||
812 | unsigned long guest_itc; | ||
813 | guest_itc = VMX(vcpu, itc_offset) + kvm_get_itc(vcpu); | ||
814 | |||
815 | if (guest_itc >= VMX(vcpu, last_itc)) { | ||
816 | VMX(vcpu, last_itc) = guest_itc; | ||
817 | return guest_itc; | ||
818 | } else | ||
819 | return VMX(vcpu, last_itc); | ||
820 | } | ||
821 | |||
822 | static inline void vcpu_set_itm(struct kvm_vcpu *vcpu, u64 val); | ||
823 | static void vcpu_set_itc(struct kvm_vcpu *vcpu, u64 val) | ||
824 | { | ||
825 | struct kvm_vcpu *v; | ||
826 | struct kvm *kvm; | ||
827 | int i; | ||
828 | long itc_offset = val - kvm_get_itc(vcpu); | ||
829 | unsigned long vitv = VCPU(vcpu, itv); | ||
830 | |||
831 | kvm = (struct kvm *)KVM_VM_BASE; | ||
832 | |||
833 | if (kvm_vcpu_is_bsp(vcpu)) { | ||
834 | for (i = 0; i < atomic_read(&kvm->online_vcpus); i++) { | ||
835 | v = (struct kvm_vcpu *)((char *)vcpu + | ||
836 | sizeof(struct kvm_vcpu_data) * i); | ||
837 | VMX(v, itc_offset) = itc_offset; | ||
838 | VMX(v, last_itc) = 0; | ||
839 | } | ||
840 | } | ||
841 | VMX(vcpu, last_itc) = 0; | ||
842 | if (VCPU(vcpu, itm) <= val) { | ||
843 | VMX(vcpu, itc_check) = 0; | ||
844 | vcpu_unpend_interrupt(vcpu, vitv); | ||
845 | } else { | ||
846 | VMX(vcpu, itc_check) = 1; | ||
847 | vcpu_set_itm(vcpu, VCPU(vcpu, itm)); | ||
848 | } | ||
849 | |||
850 | } | ||
851 | |||
852 | static inline u64 vcpu_get_itm(struct kvm_vcpu *vcpu) | ||
853 | { | ||
854 | return ((u64)VCPU(vcpu, itm)); | ||
855 | } | ||
856 | |||
857 | static inline void vcpu_set_itm(struct kvm_vcpu *vcpu, u64 val) | ||
858 | { | ||
859 | unsigned long vitv = VCPU(vcpu, itv); | ||
860 | VCPU(vcpu, itm) = val; | ||
861 | |||
862 | if (val > vcpu_get_itc(vcpu)) { | ||
863 | VMX(vcpu, itc_check) = 1; | ||
864 | vcpu_unpend_interrupt(vcpu, vitv); | ||
865 | VMX(vcpu, timer_pending) = 0; | ||
866 | } else | ||
867 | VMX(vcpu, itc_check) = 0; | ||
868 | } | ||
869 | |||
870 | #define ITV_VECTOR(itv) (itv&0xff) | ||
871 | #define ITV_IRQ_MASK(itv) (itv&(1<<16)) | ||
872 | |||
873 | static inline void vcpu_set_itv(struct kvm_vcpu *vcpu, u64 val) | ||
874 | { | ||
875 | VCPU(vcpu, itv) = val; | ||
876 | if (!ITV_IRQ_MASK(val) && vcpu->arch.timer_pending) { | ||
877 | vcpu_pend_interrupt(vcpu, ITV_VECTOR(val)); | ||
878 | vcpu->arch.timer_pending = 0; | ||
879 | } | ||
880 | } | ||
881 | |||
882 | static inline void vcpu_set_eoi(struct kvm_vcpu *vcpu, u64 val) | ||
883 | { | ||
884 | int vec; | ||
885 | |||
886 | vec = highest_inservice_irq(vcpu); | ||
887 | if (vec == NULL_VECTOR) | ||
888 | return; | ||
889 | VMX(vcpu, insvc[vec >> 6]) &= ~(1UL << (vec & 63)); | ||
890 | VCPU(vcpu, eoi) = 0; | ||
891 | vcpu->arch.irq_new_pending = 1; | ||
892 | |||
893 | } | ||
894 | |||
895 | /* See Table 5-8 in SDM vol2 for the definition */ | ||
896 | int irq_masked(struct kvm_vcpu *vcpu, int h_pending, int h_inservice) | ||
897 | { | ||
898 | union ia64_tpr vtpr; | ||
899 | |||
900 | vtpr.val = VCPU(vcpu, tpr); | ||
901 | |||
902 | if (h_inservice == NMI_VECTOR) | ||
903 | return IRQ_MASKED_BY_INSVC; | ||
904 | |||
905 | if (h_pending == NMI_VECTOR) { | ||
906 | /* Non Maskable Interrupt */ | ||
907 | return IRQ_NO_MASKED; | ||
908 | } | ||
909 | |||
910 | if (h_inservice == ExtINT_VECTOR) | ||
911 | return IRQ_MASKED_BY_INSVC; | ||
912 | |||
913 | if (h_pending == ExtINT_VECTOR) { | ||
914 | if (vtpr.mmi) { | ||
915 | /* mask all external IRQ */ | ||
916 | return IRQ_MASKED_BY_VTPR; | ||
917 | } else | ||
918 | return IRQ_NO_MASKED; | ||
919 | } | ||
920 | |||
921 | if (is_higher_irq(h_pending, h_inservice)) { | ||
922 | if (is_higher_class(h_pending, vtpr.mic + (vtpr.mmi << 4))) | ||
923 | return IRQ_NO_MASKED; | ||
924 | else | ||
925 | return IRQ_MASKED_BY_VTPR; | ||
926 | } else { | ||
927 | return IRQ_MASKED_BY_INSVC; | ||
928 | } | ||
929 | } | ||
930 | |||
931 | void vcpu_pend_interrupt(struct kvm_vcpu *vcpu, u8 vec) | ||
932 | { | ||
933 | long spsr; | ||
934 | int ret; | ||
935 | |||
936 | local_irq_save(spsr); | ||
937 | ret = test_and_set_bit(vec, &VCPU(vcpu, irr[0])); | ||
938 | local_irq_restore(spsr); | ||
939 | |||
940 | vcpu->arch.irq_new_pending = 1; | ||
941 | } | ||
942 | |||
943 | void vcpu_unpend_interrupt(struct kvm_vcpu *vcpu, u8 vec) | ||
944 | { | ||
945 | long spsr; | ||
946 | int ret; | ||
947 | |||
948 | local_irq_save(spsr); | ||
949 | ret = test_and_clear_bit(vec, &VCPU(vcpu, irr[0])); | ||
950 | local_irq_restore(spsr); | ||
951 | if (ret) { | ||
952 | vcpu->arch.irq_new_pending = 1; | ||
953 | wmb(); | ||
954 | } | ||
955 | } | ||
956 | |||
957 | void update_vhpi(struct kvm_vcpu *vcpu, int vec) | ||
958 | { | ||
959 | u64 vhpi; | ||
960 | |||
961 | if (vec == NULL_VECTOR) | ||
962 | vhpi = 0; | ||
963 | else if (vec == NMI_VECTOR) | ||
964 | vhpi = 32; | ||
965 | else if (vec == ExtINT_VECTOR) | ||
966 | vhpi = 16; | ||
967 | else | ||
968 | vhpi = vec >> 4; | ||
969 | |||
970 | VCPU(vcpu, vhpi) = vhpi; | ||
971 | if (VCPU(vcpu, vac).a_int) | ||
972 | ia64_call_vsa(PAL_VPS_SET_PENDING_INTERRUPT, | ||
973 | (u64)vcpu->arch.vpd, 0, 0, 0, 0, 0, 0); | ||
974 | } | ||
975 | |||
976 | u64 vcpu_get_ivr(struct kvm_vcpu *vcpu) | ||
977 | { | ||
978 | int vec, h_inservice, mask; | ||
979 | |||
980 | vec = highest_pending_irq(vcpu); | ||
981 | h_inservice = highest_inservice_irq(vcpu); | ||
982 | mask = irq_masked(vcpu, vec, h_inservice); | ||
983 | if (vec == NULL_VECTOR || mask == IRQ_MASKED_BY_INSVC) { | ||
984 | if (VCPU(vcpu, vhpi)) | ||
985 | update_vhpi(vcpu, NULL_VECTOR); | ||
986 | return IA64_SPURIOUS_INT_VECTOR; | ||
987 | } | ||
988 | if (mask == IRQ_MASKED_BY_VTPR) { | ||
989 | update_vhpi(vcpu, vec); | ||
990 | return IA64_SPURIOUS_INT_VECTOR; | ||
991 | } | ||
992 | VMX(vcpu, insvc[vec >> 6]) |= (1UL << (vec & 63)); | ||
993 | vcpu_unpend_interrupt(vcpu, vec); | ||
994 | return (u64)vec; | ||
995 | } | ||
996 | |||
997 | /************************************************************************** | ||
998 | Privileged operation emulation routines | ||
999 | **************************************************************************/ | ||
1000 | u64 vcpu_thash(struct kvm_vcpu *vcpu, u64 vadr) | ||
1001 | { | ||
1002 | union ia64_pta vpta; | ||
1003 | union ia64_rr vrr; | ||
1004 | u64 pval; | ||
1005 | u64 vhpt_offset; | ||
1006 | |||
1007 | vpta.val = vcpu_get_pta(vcpu); | ||
1008 | vrr.val = vcpu_get_rr(vcpu, vadr); | ||
1009 | vhpt_offset = ((vadr >> vrr.ps) << 3) & ((1UL << (vpta.size)) - 1); | ||
1010 | if (vpta.vf) { | ||
1011 | pval = ia64_call_vsa(PAL_VPS_THASH, vadr, vrr.val, | ||
1012 | vpta.val, 0, 0, 0, 0); | ||
1013 | } else { | ||
1014 | pval = (vadr & VRN_MASK) | vhpt_offset | | ||
1015 | (vpta.val << 3 >> (vpta.size + 3) << (vpta.size)); | ||
1016 | } | ||
1017 | return pval; | ||
1018 | } | ||
1019 | |||
1020 | u64 vcpu_ttag(struct kvm_vcpu *vcpu, u64 vadr) | ||
1021 | { | ||
1022 | union ia64_rr vrr; | ||
1023 | union ia64_pta vpta; | ||
1024 | u64 pval; | ||
1025 | |||
1026 | vpta.val = vcpu_get_pta(vcpu); | ||
1027 | vrr.val = vcpu_get_rr(vcpu, vadr); | ||
1028 | if (vpta.vf) { | ||
1029 | pval = ia64_call_vsa(PAL_VPS_TTAG, vadr, vrr.val, | ||
1030 | 0, 0, 0, 0, 0); | ||
1031 | } else | ||
1032 | pval = 1; | ||
1033 | |||
1034 | return pval; | ||
1035 | } | ||
1036 | |||
1037 | u64 vcpu_tak(struct kvm_vcpu *vcpu, u64 vadr) | ||
1038 | { | ||
1039 | struct thash_data *data; | ||
1040 | union ia64_pta vpta; | ||
1041 | u64 key; | ||
1042 | |||
1043 | vpta.val = vcpu_get_pta(vcpu); | ||
1044 | if (vpta.vf == 0) { | ||
1045 | key = 1; | ||
1046 | return key; | ||
1047 | } | ||
1048 | data = vtlb_lookup(vcpu, vadr, D_TLB); | ||
1049 | if (!data || !data->p) | ||
1050 | key = 1; | ||
1051 | else | ||
1052 | key = data->key; | ||
1053 | |||
1054 | return key; | ||
1055 | } | ||
1056 | |||
1057 | void kvm_thash(struct kvm_vcpu *vcpu, INST64 inst) | ||
1058 | { | ||
1059 | unsigned long thash, vadr; | ||
1060 | |||
1061 | vadr = vcpu_get_gr(vcpu, inst.M46.r3); | ||
1062 | thash = vcpu_thash(vcpu, vadr); | ||
1063 | vcpu_set_gr(vcpu, inst.M46.r1, thash, 0); | ||
1064 | } | ||
1065 | |||
1066 | void kvm_ttag(struct kvm_vcpu *vcpu, INST64 inst) | ||
1067 | { | ||
1068 | unsigned long tag, vadr; | ||
1069 | |||
1070 | vadr = vcpu_get_gr(vcpu, inst.M46.r3); | ||
1071 | tag = vcpu_ttag(vcpu, vadr); | ||
1072 | vcpu_set_gr(vcpu, inst.M46.r1, tag, 0); | ||
1073 | } | ||
1074 | |||
1075 | int vcpu_tpa(struct kvm_vcpu *vcpu, u64 vadr, unsigned long *padr) | ||
1076 | { | ||
1077 | struct thash_data *data; | ||
1078 | union ia64_isr visr, pt_isr; | ||
1079 | struct kvm_pt_regs *regs; | ||
1080 | struct ia64_psr vpsr; | ||
1081 | |||
1082 | regs = vcpu_regs(vcpu); | ||
1083 | pt_isr.val = VMX(vcpu, cr_isr); | ||
1084 | visr.val = 0; | ||
1085 | visr.ei = pt_isr.ei; | ||
1086 | visr.ir = pt_isr.ir; | ||
1087 | vpsr = *(struct ia64_psr *)&VCPU(vcpu, vpsr); | ||
1088 | visr.na = 1; | ||
1089 | |||
1090 | data = vhpt_lookup(vadr); | ||
1091 | if (data) { | ||
1092 | if (data->p == 0) { | ||
1093 | vcpu_set_isr(vcpu, visr.val); | ||
1094 | data_page_not_present(vcpu, vadr); | ||
1095 | return IA64_FAULT; | ||
1096 | } else if (data->ma == VA_MATTR_NATPAGE) { | ||
1097 | vcpu_set_isr(vcpu, visr.val); | ||
1098 | dnat_page_consumption(vcpu, vadr); | ||
1099 | return IA64_FAULT; | ||
1100 | } else { | ||
1101 | *padr = (data->gpaddr >> data->ps << data->ps) | | ||
1102 | (vadr & (PSIZE(data->ps) - 1)); | ||
1103 | return IA64_NO_FAULT; | ||
1104 | } | ||
1105 | } | ||
1106 | |||
1107 | data = vtlb_lookup(vcpu, vadr, D_TLB); | ||
1108 | if (data) { | ||
1109 | if (data->p == 0) { | ||
1110 | vcpu_set_isr(vcpu, visr.val); | ||
1111 | data_page_not_present(vcpu, vadr); | ||
1112 | return IA64_FAULT; | ||
1113 | } else if (data->ma == VA_MATTR_NATPAGE) { | ||
1114 | vcpu_set_isr(vcpu, visr.val); | ||
1115 | dnat_page_consumption(vcpu, vadr); | ||
1116 | return IA64_FAULT; | ||
1117 | } else{ | ||
1118 | *padr = ((data->ppn >> (data->ps - 12)) << data->ps) | ||
1119 | | (vadr & (PSIZE(data->ps) - 1)); | ||
1120 | return IA64_NO_FAULT; | ||
1121 | } | ||
1122 | } | ||
1123 | if (!vhpt_enabled(vcpu, vadr, NA_REF)) { | ||
1124 | if (vpsr.ic) { | ||
1125 | vcpu_set_isr(vcpu, visr.val); | ||
1126 | alt_dtlb(vcpu, vadr); | ||
1127 | return IA64_FAULT; | ||
1128 | } else { | ||
1129 | nested_dtlb(vcpu); | ||
1130 | return IA64_FAULT; | ||
1131 | } | ||
1132 | } else { | ||
1133 | if (vpsr.ic) { | ||
1134 | vcpu_set_isr(vcpu, visr.val); | ||
1135 | dvhpt_fault(vcpu, vadr); | ||
1136 | return IA64_FAULT; | ||
1137 | } else{ | ||
1138 | nested_dtlb(vcpu); | ||
1139 | return IA64_FAULT; | ||
1140 | } | ||
1141 | } | ||
1142 | |||
1143 | return IA64_NO_FAULT; | ||
1144 | } | ||
1145 | |||
1146 | int kvm_tpa(struct kvm_vcpu *vcpu, INST64 inst) | ||
1147 | { | ||
1148 | unsigned long r1, r3; | ||
1149 | |||
1150 | r3 = vcpu_get_gr(vcpu, inst.M46.r3); | ||
1151 | |||
1152 | if (vcpu_tpa(vcpu, r3, &r1)) | ||
1153 | return IA64_FAULT; | ||
1154 | |||
1155 | vcpu_set_gr(vcpu, inst.M46.r1, r1, 0); | ||
1156 | return(IA64_NO_FAULT); | ||
1157 | } | ||
1158 | |||
1159 | void kvm_tak(struct kvm_vcpu *vcpu, INST64 inst) | ||
1160 | { | ||
1161 | unsigned long r1, r3; | ||
1162 | |||
1163 | r3 = vcpu_get_gr(vcpu, inst.M46.r3); | ||
1164 | r1 = vcpu_tak(vcpu, r3); | ||
1165 | vcpu_set_gr(vcpu, inst.M46.r1, r1, 0); | ||
1166 | } | ||
1167 | |||
1168 | /************************************ | ||
1169 | * Insert/Purge translation register/cache | ||
1170 | ************************************/ | ||
1171 | void vcpu_itc_i(struct kvm_vcpu *vcpu, u64 pte, u64 itir, u64 ifa) | ||
1172 | { | ||
1173 | thash_purge_and_insert(vcpu, pte, itir, ifa, I_TLB); | ||
1174 | } | ||
1175 | |||
1176 | void vcpu_itc_d(struct kvm_vcpu *vcpu, u64 pte, u64 itir, u64 ifa) | ||
1177 | { | ||
1178 | thash_purge_and_insert(vcpu, pte, itir, ifa, D_TLB); | ||
1179 | } | ||
1180 | |||
1181 | void vcpu_itr_i(struct kvm_vcpu *vcpu, u64 slot, u64 pte, u64 itir, u64 ifa) | ||
1182 | { | ||
1183 | u64 ps, va, rid; | ||
1184 | struct thash_data *p_itr; | ||
1185 | |||
1186 | ps = itir_ps(itir); | ||
1187 | va = PAGEALIGN(ifa, ps); | ||
1188 | pte &= ~PAGE_FLAGS_RV_MASK; | ||
1189 | rid = vcpu_get_rr(vcpu, ifa); | ||
1190 | rid = rid & RR_RID_MASK; | ||
1191 | p_itr = (struct thash_data *)&vcpu->arch.itrs[slot]; | ||
1192 | vcpu_set_tr(p_itr, pte, itir, va, rid); | ||
1193 | vcpu_quick_region_set(VMX(vcpu, itr_regions), va); | ||
1194 | } | ||
1195 | |||
1196 | |||
1197 | void vcpu_itr_d(struct kvm_vcpu *vcpu, u64 slot, u64 pte, u64 itir, u64 ifa) | ||
1198 | { | ||
1199 | u64 gpfn; | ||
1200 | u64 ps, va, rid; | ||
1201 | struct thash_data *p_dtr; | ||
1202 | |||
1203 | ps = itir_ps(itir); | ||
1204 | va = PAGEALIGN(ifa, ps); | ||
1205 | pte &= ~PAGE_FLAGS_RV_MASK; | ||
1206 | |||
1207 | if (ps != _PAGE_SIZE_16M) | ||
1208 | thash_purge_entries(vcpu, va, ps); | ||
1209 | gpfn = (pte & _PAGE_PPN_MASK) >> PAGE_SHIFT; | ||
1210 | if (__gpfn_is_io(gpfn)) | ||
1211 | pte |= VTLB_PTE_IO; | ||
1212 | rid = vcpu_get_rr(vcpu, va); | ||
1213 | rid = rid & RR_RID_MASK; | ||
1214 | p_dtr = (struct thash_data *)&vcpu->arch.dtrs[slot]; | ||
1215 | vcpu_set_tr((struct thash_data *)&vcpu->arch.dtrs[slot], | ||
1216 | pte, itir, va, rid); | ||
1217 | vcpu_quick_region_set(VMX(vcpu, dtr_regions), va); | ||
1218 | } | ||
1219 | |||
1220 | void vcpu_ptr_d(struct kvm_vcpu *vcpu, u64 ifa, u64 ps) | ||
1221 | { | ||
1222 | int index; | ||
1223 | u64 va; | ||
1224 | |||
1225 | va = PAGEALIGN(ifa, ps); | ||
1226 | while ((index = vtr_find_overlap(vcpu, va, ps, D_TLB)) >= 0) | ||
1227 | vcpu->arch.dtrs[index].page_flags = 0; | ||
1228 | |||
1229 | thash_purge_entries(vcpu, va, ps); | ||
1230 | } | ||
1231 | |||
1232 | void vcpu_ptr_i(struct kvm_vcpu *vcpu, u64 ifa, u64 ps) | ||
1233 | { | ||
1234 | int index; | ||
1235 | u64 va; | ||
1236 | |||
1237 | va = PAGEALIGN(ifa, ps); | ||
1238 | while ((index = vtr_find_overlap(vcpu, va, ps, I_TLB)) >= 0) | ||
1239 | vcpu->arch.itrs[index].page_flags = 0; | ||
1240 | |||
1241 | thash_purge_entries(vcpu, va, ps); | ||
1242 | } | ||
1243 | |||
1244 | void vcpu_ptc_l(struct kvm_vcpu *vcpu, u64 va, u64 ps) | ||
1245 | { | ||
1246 | va = PAGEALIGN(va, ps); | ||
1247 | thash_purge_entries(vcpu, va, ps); | ||
1248 | } | ||
1249 | |||
1250 | void vcpu_ptc_e(struct kvm_vcpu *vcpu, u64 va) | ||
1251 | { | ||
1252 | thash_purge_all(vcpu); | ||
1253 | } | ||
1254 | |||
1255 | void vcpu_ptc_ga(struct kvm_vcpu *vcpu, u64 va, u64 ps) | ||
1256 | { | ||
1257 | struct exit_ctl_data *p = &vcpu->arch.exit_data; | ||
1258 | long psr; | ||
1259 | local_irq_save(psr); | ||
1260 | p->exit_reason = EXIT_REASON_PTC_G; | ||
1261 | |||
1262 | p->u.ptc_g_data.rr = vcpu_get_rr(vcpu, va); | ||
1263 | p->u.ptc_g_data.vaddr = va; | ||
1264 | p->u.ptc_g_data.ps = ps; | ||
1265 | vmm_transition(vcpu); | ||
1266 | /* Do Local Purge Here*/ | ||
1267 | vcpu_ptc_l(vcpu, va, ps); | ||
1268 | local_irq_restore(psr); | ||
1269 | } | ||
1270 | |||
1271 | |||
1272 | void vcpu_ptc_g(struct kvm_vcpu *vcpu, u64 va, u64 ps) | ||
1273 | { | ||
1274 | vcpu_ptc_ga(vcpu, va, ps); | ||
1275 | } | ||
1276 | |||
1277 | void kvm_ptc_e(struct kvm_vcpu *vcpu, INST64 inst) | ||
1278 | { | ||
1279 | unsigned long ifa; | ||
1280 | |||
1281 | ifa = vcpu_get_gr(vcpu, inst.M45.r3); | ||
1282 | vcpu_ptc_e(vcpu, ifa); | ||
1283 | } | ||
1284 | |||
1285 | void kvm_ptc_g(struct kvm_vcpu *vcpu, INST64 inst) | ||
1286 | { | ||
1287 | unsigned long ifa, itir; | ||
1288 | |||
1289 | ifa = vcpu_get_gr(vcpu, inst.M45.r3); | ||
1290 | itir = vcpu_get_gr(vcpu, inst.M45.r2); | ||
1291 | vcpu_ptc_g(vcpu, ifa, itir_ps(itir)); | ||
1292 | } | ||
1293 | |||
1294 | void kvm_ptc_ga(struct kvm_vcpu *vcpu, INST64 inst) | ||
1295 | { | ||
1296 | unsigned long ifa, itir; | ||
1297 | |||
1298 | ifa = vcpu_get_gr(vcpu, inst.M45.r3); | ||
1299 | itir = vcpu_get_gr(vcpu, inst.M45.r2); | ||
1300 | vcpu_ptc_ga(vcpu, ifa, itir_ps(itir)); | ||
1301 | } | ||
1302 | |||
1303 | void kvm_ptc_l(struct kvm_vcpu *vcpu, INST64 inst) | ||
1304 | { | ||
1305 | unsigned long ifa, itir; | ||
1306 | |||
1307 | ifa = vcpu_get_gr(vcpu, inst.M45.r3); | ||
1308 | itir = vcpu_get_gr(vcpu, inst.M45.r2); | ||
1309 | vcpu_ptc_l(vcpu, ifa, itir_ps(itir)); | ||
1310 | } | ||
1311 | |||
1312 | void kvm_ptr_d(struct kvm_vcpu *vcpu, INST64 inst) | ||
1313 | { | ||
1314 | unsigned long ifa, itir; | ||
1315 | |||
1316 | ifa = vcpu_get_gr(vcpu, inst.M45.r3); | ||
1317 | itir = vcpu_get_gr(vcpu, inst.M45.r2); | ||
1318 | vcpu_ptr_d(vcpu, ifa, itir_ps(itir)); | ||
1319 | } | ||
1320 | |||
1321 | void kvm_ptr_i(struct kvm_vcpu *vcpu, INST64 inst) | ||
1322 | { | ||
1323 | unsigned long ifa, itir; | ||
1324 | |||
1325 | ifa = vcpu_get_gr(vcpu, inst.M45.r3); | ||
1326 | itir = vcpu_get_gr(vcpu, inst.M45.r2); | ||
1327 | vcpu_ptr_i(vcpu, ifa, itir_ps(itir)); | ||
1328 | } | ||
1329 | |||
1330 | void kvm_itr_d(struct kvm_vcpu *vcpu, INST64 inst) | ||
1331 | { | ||
1332 | unsigned long itir, ifa, pte, slot; | ||
1333 | |||
1334 | slot = vcpu_get_gr(vcpu, inst.M45.r3); | ||
1335 | pte = vcpu_get_gr(vcpu, inst.M45.r2); | ||
1336 | itir = vcpu_get_itir(vcpu); | ||
1337 | ifa = vcpu_get_ifa(vcpu); | ||
1338 | vcpu_itr_d(vcpu, slot, pte, itir, ifa); | ||
1339 | } | ||
1340 | |||
1341 | |||
1342 | |||
1343 | void kvm_itr_i(struct kvm_vcpu *vcpu, INST64 inst) | ||
1344 | { | ||
1345 | unsigned long itir, ifa, pte, slot; | ||
1346 | |||
1347 | slot = vcpu_get_gr(vcpu, inst.M45.r3); | ||
1348 | pte = vcpu_get_gr(vcpu, inst.M45.r2); | ||
1349 | itir = vcpu_get_itir(vcpu); | ||
1350 | ifa = vcpu_get_ifa(vcpu); | ||
1351 | vcpu_itr_i(vcpu, slot, pte, itir, ifa); | ||
1352 | } | ||
1353 | |||
1354 | void kvm_itc_d(struct kvm_vcpu *vcpu, INST64 inst) | ||
1355 | { | ||
1356 | unsigned long itir, ifa, pte; | ||
1357 | |||
1358 | itir = vcpu_get_itir(vcpu); | ||
1359 | ifa = vcpu_get_ifa(vcpu); | ||
1360 | pte = vcpu_get_gr(vcpu, inst.M45.r2); | ||
1361 | vcpu_itc_d(vcpu, pte, itir, ifa); | ||
1362 | } | ||
1363 | |||
1364 | void kvm_itc_i(struct kvm_vcpu *vcpu, INST64 inst) | ||
1365 | { | ||
1366 | unsigned long itir, ifa, pte; | ||
1367 | |||
1368 | itir = vcpu_get_itir(vcpu); | ||
1369 | ifa = vcpu_get_ifa(vcpu); | ||
1370 | pte = vcpu_get_gr(vcpu, inst.M45.r2); | ||
1371 | vcpu_itc_i(vcpu, pte, itir, ifa); | ||
1372 | } | ||
1373 | |||
1374 | /************************************* | ||
1375 | * Moves to semi-privileged registers | ||
1376 | *************************************/ | ||
1377 | |||
1378 | void kvm_mov_to_ar_imm(struct kvm_vcpu *vcpu, INST64 inst) | ||
1379 | { | ||
1380 | unsigned long imm; | ||
1381 | |||
1382 | if (inst.M30.s) | ||
1383 | imm = -inst.M30.imm; | ||
1384 | else | ||
1385 | imm = inst.M30.imm; | ||
1386 | |||
1387 | vcpu_set_itc(vcpu, imm); | ||
1388 | } | ||
1389 | |||
1390 | void kvm_mov_to_ar_reg(struct kvm_vcpu *vcpu, INST64 inst) | ||
1391 | { | ||
1392 | unsigned long r2; | ||
1393 | |||
1394 | r2 = vcpu_get_gr(vcpu, inst.M29.r2); | ||
1395 | vcpu_set_itc(vcpu, r2); | ||
1396 | } | ||
1397 | |||
1398 | void kvm_mov_from_ar_reg(struct kvm_vcpu *vcpu, INST64 inst) | ||
1399 | { | ||
1400 | unsigned long r1; | ||
1401 | |||
1402 | r1 = vcpu_get_itc(vcpu); | ||
1403 | vcpu_set_gr(vcpu, inst.M31.r1, r1, 0); | ||
1404 | } | ||
1405 | |||
1406 | /************************************************************************** | ||
1407 | struct kvm_vcpu protection key register access routines | ||
1408 | **************************************************************************/ | ||
1409 | |||
1410 | unsigned long vcpu_get_pkr(struct kvm_vcpu *vcpu, unsigned long reg) | ||
1411 | { | ||
1412 | return ((unsigned long)ia64_get_pkr(reg)); | ||
1413 | } | ||
1414 | |||
1415 | void vcpu_set_pkr(struct kvm_vcpu *vcpu, unsigned long reg, unsigned long val) | ||
1416 | { | ||
1417 | ia64_set_pkr(reg, val); | ||
1418 | } | ||
1419 | |||
1420 | /******************************** | ||
1421 | * Moves to privileged registers | ||
1422 | ********************************/ | ||
1423 | unsigned long vcpu_set_rr(struct kvm_vcpu *vcpu, unsigned long reg, | ||
1424 | unsigned long val) | ||
1425 | { | ||
1426 | union ia64_rr oldrr, newrr; | ||
1427 | unsigned long rrval; | ||
1428 | struct exit_ctl_data *p = &vcpu->arch.exit_data; | ||
1429 | unsigned long psr; | ||
1430 | |||
1431 | oldrr.val = vcpu_get_rr(vcpu, reg); | ||
1432 | newrr.val = val; | ||
1433 | vcpu->arch.vrr[reg >> VRN_SHIFT] = val; | ||
1434 | |||
1435 | switch ((unsigned long)(reg >> VRN_SHIFT)) { | ||
1436 | case VRN6: | ||
1437 | vcpu->arch.vmm_rr = vrrtomrr(val); | ||
1438 | local_irq_save(psr); | ||
1439 | p->exit_reason = EXIT_REASON_SWITCH_RR6; | ||
1440 | vmm_transition(vcpu); | ||
1441 | local_irq_restore(psr); | ||
1442 | break; | ||
1443 | case VRN4: | ||
1444 | rrval = vrrtomrr(val); | ||
1445 | vcpu->arch.metaphysical_saved_rr4 = rrval; | ||
1446 | if (!is_physical_mode(vcpu)) | ||
1447 | ia64_set_rr(reg, rrval); | ||
1448 | break; | ||
1449 | case VRN0: | ||
1450 | rrval = vrrtomrr(val); | ||
1451 | vcpu->arch.metaphysical_saved_rr0 = rrval; | ||
1452 | if (!is_physical_mode(vcpu)) | ||
1453 | ia64_set_rr(reg, rrval); | ||
1454 | break; | ||
1455 | default: | ||
1456 | ia64_set_rr(reg, vrrtomrr(val)); | ||
1457 | break; | ||
1458 | } | ||
1459 | |||
1460 | return (IA64_NO_FAULT); | ||
1461 | } | ||
1462 | |||
1463 | void kvm_mov_to_rr(struct kvm_vcpu *vcpu, INST64 inst) | ||
1464 | { | ||
1465 | unsigned long r3, r2; | ||
1466 | |||
1467 | r3 = vcpu_get_gr(vcpu, inst.M42.r3); | ||
1468 | r2 = vcpu_get_gr(vcpu, inst.M42.r2); | ||
1469 | vcpu_set_rr(vcpu, r3, r2); | ||
1470 | } | ||
1471 | |||
1472 | void kvm_mov_to_dbr(struct kvm_vcpu *vcpu, INST64 inst) | ||
1473 | { | ||
1474 | } | ||
1475 | |||
1476 | void kvm_mov_to_ibr(struct kvm_vcpu *vcpu, INST64 inst) | ||
1477 | { | ||
1478 | } | ||
1479 | |||
1480 | void kvm_mov_to_pmc(struct kvm_vcpu *vcpu, INST64 inst) | ||
1481 | { | ||
1482 | unsigned long r3, r2; | ||
1483 | |||
1484 | r3 = vcpu_get_gr(vcpu, inst.M42.r3); | ||
1485 | r2 = vcpu_get_gr(vcpu, inst.M42.r2); | ||
1486 | vcpu_set_pmc(vcpu, r3, r2); | ||
1487 | } | ||
1488 | |||
1489 | void kvm_mov_to_pmd(struct kvm_vcpu *vcpu, INST64 inst) | ||
1490 | { | ||
1491 | unsigned long r3, r2; | ||
1492 | |||
1493 | r3 = vcpu_get_gr(vcpu, inst.M42.r3); | ||
1494 | r2 = vcpu_get_gr(vcpu, inst.M42.r2); | ||
1495 | vcpu_set_pmd(vcpu, r3, r2); | ||
1496 | } | ||
1497 | |||
1498 | void kvm_mov_to_pkr(struct kvm_vcpu *vcpu, INST64 inst) | ||
1499 | { | ||
1500 | u64 r3, r2; | ||
1501 | |||
1502 | r3 = vcpu_get_gr(vcpu, inst.M42.r3); | ||
1503 | r2 = vcpu_get_gr(vcpu, inst.M42.r2); | ||
1504 | vcpu_set_pkr(vcpu, r3, r2); | ||
1505 | } | ||
1506 | |||
1507 | void kvm_mov_from_rr(struct kvm_vcpu *vcpu, INST64 inst) | ||
1508 | { | ||
1509 | unsigned long r3, r1; | ||
1510 | |||
1511 | r3 = vcpu_get_gr(vcpu, inst.M43.r3); | ||
1512 | r1 = vcpu_get_rr(vcpu, r3); | ||
1513 | vcpu_set_gr(vcpu, inst.M43.r1, r1, 0); | ||
1514 | } | ||
1515 | |||
1516 | void kvm_mov_from_pkr(struct kvm_vcpu *vcpu, INST64 inst) | ||
1517 | { | ||
1518 | unsigned long r3, r1; | ||
1519 | |||
1520 | r3 = vcpu_get_gr(vcpu, inst.M43.r3); | ||
1521 | r1 = vcpu_get_pkr(vcpu, r3); | ||
1522 | vcpu_set_gr(vcpu, inst.M43.r1, r1, 0); | ||
1523 | } | ||
1524 | |||
1525 | void kvm_mov_from_dbr(struct kvm_vcpu *vcpu, INST64 inst) | ||
1526 | { | ||
1527 | unsigned long r3, r1; | ||
1528 | |||
1529 | r3 = vcpu_get_gr(vcpu, inst.M43.r3); | ||
1530 | r1 = vcpu_get_dbr(vcpu, r3); | ||
1531 | vcpu_set_gr(vcpu, inst.M43.r1, r1, 0); | ||
1532 | } | ||
1533 | |||
1534 | void kvm_mov_from_ibr(struct kvm_vcpu *vcpu, INST64 inst) | ||
1535 | { | ||
1536 | unsigned long r3, r1; | ||
1537 | |||
1538 | r3 = vcpu_get_gr(vcpu, inst.M43.r3); | ||
1539 | r1 = vcpu_get_ibr(vcpu, r3); | ||
1540 | vcpu_set_gr(vcpu, inst.M43.r1, r1, 0); | ||
1541 | } | ||
1542 | |||
1543 | void kvm_mov_from_pmc(struct kvm_vcpu *vcpu, INST64 inst) | ||
1544 | { | ||
1545 | unsigned long r3, r1; | ||
1546 | |||
1547 | r3 = vcpu_get_gr(vcpu, inst.M43.r3); | ||
1548 | r1 = vcpu_get_pmc(vcpu, r3); | ||
1549 | vcpu_set_gr(vcpu, inst.M43.r1, r1, 0); | ||
1550 | } | ||
1551 | |||
1552 | unsigned long vcpu_get_cpuid(struct kvm_vcpu *vcpu, unsigned long reg) | ||
1553 | { | ||
1554 | /* FIXME: This could get called as a result of a rsvd-reg fault */ | ||
1555 | if (reg > (ia64_get_cpuid(3) & 0xff)) | ||
1556 | return 0; | ||
1557 | else | ||
1558 | return ia64_get_cpuid(reg); | ||
1559 | } | ||
1560 | |||
1561 | void kvm_mov_from_cpuid(struct kvm_vcpu *vcpu, INST64 inst) | ||
1562 | { | ||
1563 | unsigned long r3, r1; | ||
1564 | |||
1565 | r3 = vcpu_get_gr(vcpu, inst.M43.r3); | ||
1566 | r1 = vcpu_get_cpuid(vcpu, r3); | ||
1567 | vcpu_set_gr(vcpu, inst.M43.r1, r1, 0); | ||
1568 | } | ||
1569 | |||
1570 | void vcpu_set_tpr(struct kvm_vcpu *vcpu, unsigned long val) | ||
1571 | { | ||
1572 | VCPU(vcpu, tpr) = val; | ||
1573 | vcpu->arch.irq_check = 1; | ||
1574 | } | ||
1575 | |||
1576 | unsigned long kvm_mov_to_cr(struct kvm_vcpu *vcpu, INST64 inst) | ||
1577 | { | ||
1578 | unsigned long r2; | ||
1579 | |||
1580 | r2 = vcpu_get_gr(vcpu, inst.M32.r2); | ||
1581 | VCPU(vcpu, vcr[inst.M32.cr3]) = r2; | ||
1582 | |||
1583 | switch (inst.M32.cr3) { | ||
1584 | case 0: | ||
1585 | vcpu_set_dcr(vcpu, r2); | ||
1586 | break; | ||
1587 | case 1: | ||
1588 | vcpu_set_itm(vcpu, r2); | ||
1589 | break; | ||
1590 | case 66: | ||
1591 | vcpu_set_tpr(vcpu, r2); | ||
1592 | break; | ||
1593 | case 67: | ||
1594 | vcpu_set_eoi(vcpu, r2); | ||
1595 | break; | ||
1596 | default: | ||
1597 | break; | ||
1598 | } | ||
1599 | |||
1600 | return 0; | ||
1601 | } | ||
1602 | |||
1603 | unsigned long kvm_mov_from_cr(struct kvm_vcpu *vcpu, INST64 inst) | ||
1604 | { | ||
1605 | unsigned long tgt = inst.M33.r1; | ||
1606 | unsigned long val; | ||
1607 | |||
1608 | switch (inst.M33.cr3) { | ||
1609 | case 65: | ||
1610 | val = vcpu_get_ivr(vcpu); | ||
1611 | vcpu_set_gr(vcpu, tgt, val, 0); | ||
1612 | break; | ||
1613 | |||
1614 | case 67: | ||
1615 | vcpu_set_gr(vcpu, tgt, 0L, 0); | ||
1616 | break; | ||
1617 | default: | ||
1618 | val = VCPU(vcpu, vcr[inst.M33.cr3]); | ||
1619 | vcpu_set_gr(vcpu, tgt, val, 0); | ||
1620 | break; | ||
1621 | } | ||
1622 | |||
1623 | return 0; | ||
1624 | } | ||
1625 | |||
1626 | void vcpu_set_psr(struct kvm_vcpu *vcpu, unsigned long val) | ||
1627 | { | ||
1628 | |||
1629 | unsigned long mask; | ||
1630 | struct kvm_pt_regs *regs; | ||
1631 | struct ia64_psr old_psr, new_psr; | ||
1632 | |||
1633 | old_psr = *(struct ia64_psr *)&VCPU(vcpu, vpsr); | ||
1634 | |||
1635 | regs = vcpu_regs(vcpu); | ||
1636 | /* We only support guest as: | ||
1637 | * vpsr.pk = 0 | ||
1638 | * vpsr.is = 0 | ||
1639 | * Otherwise panic | ||
1640 | */ | ||
1641 | if (val & (IA64_PSR_PK | IA64_PSR_IS | IA64_PSR_VM)) | ||
1642 | panic_vm(vcpu, "Only support guests with vpsr.pk =0 " | ||
1643 | "& vpsr.is=0\n"); | ||
1644 | |||
1645 | /* | ||
1646 | * For those IA64_PSR bits: id/da/dd/ss/ed/ia | ||
1647 | * Since these bits will become 0, after success execution of each | ||
1648 | * instruction, we will change set them to mIA64_PSR | ||
1649 | */ | ||
1650 | VCPU(vcpu, vpsr) = val | ||
1651 | & (~(IA64_PSR_ID | IA64_PSR_DA | IA64_PSR_DD | | ||
1652 | IA64_PSR_SS | IA64_PSR_ED | IA64_PSR_IA)); | ||
1653 | |||
1654 | if (!old_psr.i && (val & IA64_PSR_I)) { | ||
1655 | /* vpsr.i 0->1 */ | ||
1656 | vcpu->arch.irq_check = 1; | ||
1657 | } | ||
1658 | new_psr = *(struct ia64_psr *)&VCPU(vcpu, vpsr); | ||
1659 | |||
1660 | /* | ||
1661 | * All vIA64_PSR bits shall go to mPSR (v->tf->tf_special.psr) | ||
1662 | * , except for the following bits: | ||
1663 | * ic/i/dt/si/rt/mc/it/bn/vm | ||
1664 | */ | ||
1665 | mask = IA64_PSR_IC + IA64_PSR_I + IA64_PSR_DT + IA64_PSR_SI + | ||
1666 | IA64_PSR_RT + IA64_PSR_MC + IA64_PSR_IT + IA64_PSR_BN + | ||
1667 | IA64_PSR_VM; | ||
1668 | |||
1669 | regs->cr_ipsr = (regs->cr_ipsr & mask) | (val & (~mask)); | ||
1670 | |||
1671 | check_mm_mode_switch(vcpu, old_psr, new_psr); | ||
1672 | |||
1673 | return ; | ||
1674 | } | ||
1675 | |||
1676 | unsigned long vcpu_cover(struct kvm_vcpu *vcpu) | ||
1677 | { | ||
1678 | struct ia64_psr vpsr; | ||
1679 | |||
1680 | struct kvm_pt_regs *regs = vcpu_regs(vcpu); | ||
1681 | vpsr = *(struct ia64_psr *)&VCPU(vcpu, vpsr); | ||
1682 | |||
1683 | if (!vpsr.ic) | ||
1684 | VCPU(vcpu, ifs) = regs->cr_ifs; | ||
1685 | regs->cr_ifs = IA64_IFS_V; | ||
1686 | return (IA64_NO_FAULT); | ||
1687 | } | ||
1688 | |||
1689 | |||
1690 | |||
1691 | /************************************************************************** | ||
1692 | VCPU banked general register access routines | ||
1693 | **************************************************************************/ | ||
1694 | #define vcpu_bsw0_unat(i, b0unat, b1unat, runat, VMM_PT_REGS_R16_SLOT) \ | ||
1695 | do { \ | ||
1696 | __asm__ __volatile__ ( \ | ||
1697 | ";;extr.u %0 = %3,%6,16;;\n" \ | ||
1698 | "dep %1 = %0, %1, 0, 16;;\n" \ | ||
1699 | "st8 [%4] = %1\n" \ | ||
1700 | "extr.u %0 = %2, 16, 16;;\n" \ | ||
1701 | "dep %3 = %0, %3, %6, 16;;\n" \ | ||
1702 | "st8 [%5] = %3\n" \ | ||
1703 | ::"r"(i), "r"(*b1unat), "r"(*b0unat), \ | ||
1704 | "r"(*runat), "r"(b1unat), "r"(runat), \ | ||
1705 | "i"(VMM_PT_REGS_R16_SLOT) : "memory"); \ | ||
1706 | } while (0) | ||
1707 | |||
1708 | void vcpu_bsw0(struct kvm_vcpu *vcpu) | ||
1709 | { | ||
1710 | unsigned long i; | ||
1711 | |||
1712 | struct kvm_pt_regs *regs = vcpu_regs(vcpu); | ||
1713 | unsigned long *r = ®s->r16; | ||
1714 | unsigned long *b0 = &VCPU(vcpu, vbgr[0]); | ||
1715 | unsigned long *b1 = &VCPU(vcpu, vgr[0]); | ||
1716 | unsigned long *runat = ®s->eml_unat; | ||
1717 | unsigned long *b0unat = &VCPU(vcpu, vbnat); | ||
1718 | unsigned long *b1unat = &VCPU(vcpu, vnat); | ||
1719 | |||
1720 | |||
1721 | if (VCPU(vcpu, vpsr) & IA64_PSR_BN) { | ||
1722 | for (i = 0; i < 16; i++) { | ||
1723 | *b1++ = *r; | ||
1724 | *r++ = *b0++; | ||
1725 | } | ||
1726 | vcpu_bsw0_unat(i, b0unat, b1unat, runat, | ||
1727 | VMM_PT_REGS_R16_SLOT); | ||
1728 | VCPU(vcpu, vpsr) &= ~IA64_PSR_BN; | ||
1729 | } | ||
1730 | } | ||
1731 | |||
1732 | #define vcpu_bsw1_unat(i, b0unat, b1unat, runat, VMM_PT_REGS_R16_SLOT) \ | ||
1733 | do { \ | ||
1734 | __asm__ __volatile__ (";;extr.u %0 = %3, %6, 16;;\n" \ | ||
1735 | "dep %1 = %0, %1, 16, 16;;\n" \ | ||
1736 | "st8 [%4] = %1\n" \ | ||
1737 | "extr.u %0 = %2, 0, 16;;\n" \ | ||
1738 | "dep %3 = %0, %3, %6, 16;;\n" \ | ||
1739 | "st8 [%5] = %3\n" \ | ||
1740 | ::"r"(i), "r"(*b0unat), "r"(*b1unat), \ | ||
1741 | "r"(*runat), "r"(b0unat), "r"(runat), \ | ||
1742 | "i"(VMM_PT_REGS_R16_SLOT) : "memory"); \ | ||
1743 | } while (0) | ||
1744 | |||
1745 | void vcpu_bsw1(struct kvm_vcpu *vcpu) | ||
1746 | { | ||
1747 | unsigned long i; | ||
1748 | struct kvm_pt_regs *regs = vcpu_regs(vcpu); | ||
1749 | unsigned long *r = ®s->r16; | ||
1750 | unsigned long *b0 = &VCPU(vcpu, vbgr[0]); | ||
1751 | unsigned long *b1 = &VCPU(vcpu, vgr[0]); | ||
1752 | unsigned long *runat = ®s->eml_unat; | ||
1753 | unsigned long *b0unat = &VCPU(vcpu, vbnat); | ||
1754 | unsigned long *b1unat = &VCPU(vcpu, vnat); | ||
1755 | |||
1756 | if (!(VCPU(vcpu, vpsr) & IA64_PSR_BN)) { | ||
1757 | for (i = 0; i < 16; i++) { | ||
1758 | *b0++ = *r; | ||
1759 | *r++ = *b1++; | ||
1760 | } | ||
1761 | vcpu_bsw1_unat(i, b0unat, b1unat, runat, | ||
1762 | VMM_PT_REGS_R16_SLOT); | ||
1763 | VCPU(vcpu, vpsr) |= IA64_PSR_BN; | ||
1764 | } | ||
1765 | } | ||
1766 | |||
1767 | void vcpu_rfi(struct kvm_vcpu *vcpu) | ||
1768 | { | ||
1769 | unsigned long ifs, psr; | ||
1770 | struct kvm_pt_regs *regs = vcpu_regs(vcpu); | ||
1771 | |||
1772 | psr = VCPU(vcpu, ipsr); | ||
1773 | if (psr & IA64_PSR_BN) | ||
1774 | vcpu_bsw1(vcpu); | ||
1775 | else | ||
1776 | vcpu_bsw0(vcpu); | ||
1777 | vcpu_set_psr(vcpu, psr); | ||
1778 | ifs = VCPU(vcpu, ifs); | ||
1779 | if (ifs >> 63) | ||
1780 | regs->cr_ifs = ifs; | ||
1781 | regs->cr_iip = VCPU(vcpu, iip); | ||
1782 | } | ||
1783 | |||
1784 | /* | ||
1785 | VPSR can't keep track of below bits of guest PSR | ||
1786 | This function gets guest PSR | ||
1787 | */ | ||
1788 | |||
1789 | unsigned long vcpu_get_psr(struct kvm_vcpu *vcpu) | ||
1790 | { | ||
1791 | unsigned long mask; | ||
1792 | struct kvm_pt_regs *regs = vcpu_regs(vcpu); | ||
1793 | |||
1794 | mask = IA64_PSR_BE | IA64_PSR_UP | IA64_PSR_AC | IA64_PSR_MFL | | ||
1795 | IA64_PSR_MFH | IA64_PSR_CPL | IA64_PSR_RI; | ||
1796 | return (VCPU(vcpu, vpsr) & ~mask) | (regs->cr_ipsr & mask); | ||
1797 | } | ||
1798 | |||
1799 | void kvm_rsm(struct kvm_vcpu *vcpu, INST64 inst) | ||
1800 | { | ||
1801 | unsigned long vpsr; | ||
1802 | unsigned long imm24 = (inst.M44.i<<23) | (inst.M44.i2<<21) | ||
1803 | | inst.M44.imm; | ||
1804 | |||
1805 | vpsr = vcpu_get_psr(vcpu); | ||
1806 | vpsr &= (~imm24); | ||
1807 | vcpu_set_psr(vcpu, vpsr); | ||
1808 | } | ||
1809 | |||
1810 | void kvm_ssm(struct kvm_vcpu *vcpu, INST64 inst) | ||
1811 | { | ||
1812 | unsigned long vpsr; | ||
1813 | unsigned long imm24 = (inst.M44.i << 23) | (inst.M44.i2 << 21) | ||
1814 | | inst.M44.imm; | ||
1815 | |||
1816 | vpsr = vcpu_get_psr(vcpu); | ||
1817 | vpsr |= imm24; | ||
1818 | vcpu_set_psr(vcpu, vpsr); | ||
1819 | } | ||
1820 | |||
1821 | /* Generate Mask | ||
1822 | * Parameter: | ||
1823 | * bit -- starting bit | ||
1824 | * len -- how many bits | ||
1825 | */ | ||
1826 | #define MASK(bit,len) \ | ||
1827 | ({ \ | ||
1828 | __u64 ret; \ | ||
1829 | \ | ||
1830 | __asm __volatile("dep %0=-1, r0, %1, %2"\ | ||
1831 | : "=r" (ret): \ | ||
1832 | "M" (bit), \ | ||
1833 | "M" (len)); \ | ||
1834 | ret; \ | ||
1835 | }) | ||
1836 | |||
1837 | void vcpu_set_psr_l(struct kvm_vcpu *vcpu, unsigned long val) | ||
1838 | { | ||
1839 | val = (val & MASK(0, 32)) | (vcpu_get_psr(vcpu) & MASK(32, 32)); | ||
1840 | vcpu_set_psr(vcpu, val); | ||
1841 | } | ||
1842 | |||
1843 | void kvm_mov_to_psr(struct kvm_vcpu *vcpu, INST64 inst) | ||
1844 | { | ||
1845 | unsigned long val; | ||
1846 | |||
1847 | val = vcpu_get_gr(vcpu, inst.M35.r2); | ||
1848 | vcpu_set_psr_l(vcpu, val); | ||
1849 | } | ||
1850 | |||
1851 | void kvm_mov_from_psr(struct kvm_vcpu *vcpu, INST64 inst) | ||
1852 | { | ||
1853 | unsigned long val; | ||
1854 | |||
1855 | val = vcpu_get_psr(vcpu); | ||
1856 | val = (val & MASK(0, 32)) | (val & MASK(35, 2)); | ||
1857 | vcpu_set_gr(vcpu, inst.M33.r1, val, 0); | ||
1858 | } | ||
1859 | |||
1860 | void vcpu_increment_iip(struct kvm_vcpu *vcpu) | ||
1861 | { | ||
1862 | struct kvm_pt_regs *regs = vcpu_regs(vcpu); | ||
1863 | struct ia64_psr *ipsr = (struct ia64_psr *)®s->cr_ipsr; | ||
1864 | if (ipsr->ri == 2) { | ||
1865 | ipsr->ri = 0; | ||
1866 | regs->cr_iip += 16; | ||
1867 | } else | ||
1868 | ipsr->ri++; | ||
1869 | } | ||
1870 | |||
1871 | void vcpu_decrement_iip(struct kvm_vcpu *vcpu) | ||
1872 | { | ||
1873 | struct kvm_pt_regs *regs = vcpu_regs(vcpu); | ||
1874 | struct ia64_psr *ipsr = (struct ia64_psr *)®s->cr_ipsr; | ||
1875 | |||
1876 | if (ipsr->ri == 0) { | ||
1877 | ipsr->ri = 2; | ||
1878 | regs->cr_iip -= 16; | ||
1879 | } else | ||
1880 | ipsr->ri--; | ||
1881 | } | ||
1882 | |||
1883 | /** Emulate a privileged operation. | ||
1884 | * | ||
1885 | * | ||
1886 | * @param vcpu virtual cpu | ||
1887 | * @cause the reason cause virtualization fault | ||
1888 | * @opcode the instruction code which cause virtualization fault | ||
1889 | */ | ||
1890 | |||
1891 | void kvm_emulate(struct kvm_vcpu *vcpu, struct kvm_pt_regs *regs) | ||
1892 | { | ||
1893 | unsigned long status, cause, opcode ; | ||
1894 | INST64 inst; | ||
1895 | |||
1896 | status = IA64_NO_FAULT; | ||
1897 | cause = VMX(vcpu, cause); | ||
1898 | opcode = VMX(vcpu, opcode); | ||
1899 | inst.inst = opcode; | ||
1900 | /* | ||
1901 | * Switch to actual virtual rid in rr0 and rr4, | ||
1902 | * which is required by some tlb related instructions. | ||
1903 | */ | ||
1904 | prepare_if_physical_mode(vcpu); | ||
1905 | |||
1906 | switch (cause) { | ||
1907 | case EVENT_RSM: | ||
1908 | kvm_rsm(vcpu, inst); | ||
1909 | break; | ||
1910 | case EVENT_SSM: | ||
1911 | kvm_ssm(vcpu, inst); | ||
1912 | break; | ||
1913 | case EVENT_MOV_TO_PSR: | ||
1914 | kvm_mov_to_psr(vcpu, inst); | ||
1915 | break; | ||
1916 | case EVENT_MOV_FROM_PSR: | ||
1917 | kvm_mov_from_psr(vcpu, inst); | ||
1918 | break; | ||
1919 | case EVENT_MOV_FROM_CR: | ||
1920 | kvm_mov_from_cr(vcpu, inst); | ||
1921 | break; | ||
1922 | case EVENT_MOV_TO_CR: | ||
1923 | kvm_mov_to_cr(vcpu, inst); | ||
1924 | break; | ||
1925 | case EVENT_BSW_0: | ||
1926 | vcpu_bsw0(vcpu); | ||
1927 | break; | ||
1928 | case EVENT_BSW_1: | ||
1929 | vcpu_bsw1(vcpu); | ||
1930 | break; | ||
1931 | case EVENT_COVER: | ||
1932 | vcpu_cover(vcpu); | ||
1933 | break; | ||
1934 | case EVENT_RFI: | ||
1935 | vcpu_rfi(vcpu); | ||
1936 | break; | ||
1937 | case EVENT_ITR_D: | ||
1938 | kvm_itr_d(vcpu, inst); | ||
1939 | break; | ||
1940 | case EVENT_ITR_I: | ||
1941 | kvm_itr_i(vcpu, inst); | ||
1942 | break; | ||
1943 | case EVENT_PTR_D: | ||
1944 | kvm_ptr_d(vcpu, inst); | ||
1945 | break; | ||
1946 | case EVENT_PTR_I: | ||
1947 | kvm_ptr_i(vcpu, inst); | ||
1948 | break; | ||
1949 | case EVENT_ITC_D: | ||
1950 | kvm_itc_d(vcpu, inst); | ||
1951 | break; | ||
1952 | case EVENT_ITC_I: | ||
1953 | kvm_itc_i(vcpu, inst); | ||
1954 | break; | ||
1955 | case EVENT_PTC_L: | ||
1956 | kvm_ptc_l(vcpu, inst); | ||
1957 | break; | ||
1958 | case EVENT_PTC_G: | ||
1959 | kvm_ptc_g(vcpu, inst); | ||
1960 | break; | ||
1961 | case EVENT_PTC_GA: | ||
1962 | kvm_ptc_ga(vcpu, inst); | ||
1963 | break; | ||
1964 | case EVENT_PTC_E: | ||
1965 | kvm_ptc_e(vcpu, inst); | ||
1966 | break; | ||
1967 | case EVENT_MOV_TO_RR: | ||
1968 | kvm_mov_to_rr(vcpu, inst); | ||
1969 | break; | ||
1970 | case EVENT_MOV_FROM_RR: | ||
1971 | kvm_mov_from_rr(vcpu, inst); | ||
1972 | break; | ||
1973 | case EVENT_THASH: | ||
1974 | kvm_thash(vcpu, inst); | ||
1975 | break; | ||
1976 | case EVENT_TTAG: | ||
1977 | kvm_ttag(vcpu, inst); | ||
1978 | break; | ||
1979 | case EVENT_TPA: | ||
1980 | status = kvm_tpa(vcpu, inst); | ||
1981 | break; | ||
1982 | case EVENT_TAK: | ||
1983 | kvm_tak(vcpu, inst); | ||
1984 | break; | ||
1985 | case EVENT_MOV_TO_AR_IMM: | ||
1986 | kvm_mov_to_ar_imm(vcpu, inst); | ||
1987 | break; | ||
1988 | case EVENT_MOV_TO_AR: | ||
1989 | kvm_mov_to_ar_reg(vcpu, inst); | ||
1990 | break; | ||
1991 | case EVENT_MOV_FROM_AR: | ||
1992 | kvm_mov_from_ar_reg(vcpu, inst); | ||
1993 | break; | ||
1994 | case EVENT_MOV_TO_DBR: | ||
1995 | kvm_mov_to_dbr(vcpu, inst); | ||
1996 | break; | ||
1997 | case EVENT_MOV_TO_IBR: | ||
1998 | kvm_mov_to_ibr(vcpu, inst); | ||
1999 | break; | ||
2000 | case EVENT_MOV_TO_PMC: | ||
2001 | kvm_mov_to_pmc(vcpu, inst); | ||
2002 | break; | ||
2003 | case EVENT_MOV_TO_PMD: | ||
2004 | kvm_mov_to_pmd(vcpu, inst); | ||
2005 | break; | ||
2006 | case EVENT_MOV_TO_PKR: | ||
2007 | kvm_mov_to_pkr(vcpu, inst); | ||
2008 | break; | ||
2009 | case EVENT_MOV_FROM_DBR: | ||
2010 | kvm_mov_from_dbr(vcpu, inst); | ||
2011 | break; | ||
2012 | case EVENT_MOV_FROM_IBR: | ||
2013 | kvm_mov_from_ibr(vcpu, inst); | ||
2014 | break; | ||
2015 | case EVENT_MOV_FROM_PMC: | ||
2016 | kvm_mov_from_pmc(vcpu, inst); | ||
2017 | break; | ||
2018 | case EVENT_MOV_FROM_PKR: | ||
2019 | kvm_mov_from_pkr(vcpu, inst); | ||
2020 | break; | ||
2021 | case EVENT_MOV_FROM_CPUID: | ||
2022 | kvm_mov_from_cpuid(vcpu, inst); | ||
2023 | break; | ||
2024 | case EVENT_VMSW: | ||
2025 | status = IA64_FAULT; | ||
2026 | break; | ||
2027 | default: | ||
2028 | break; | ||
2029 | }; | ||
2030 | /*Assume all status is NO_FAULT ?*/ | ||
2031 | if (status == IA64_NO_FAULT && cause != EVENT_RFI) | ||
2032 | vcpu_increment_iip(vcpu); | ||
2033 | |||
2034 | recover_if_physical_mode(vcpu); | ||
2035 | } | ||
2036 | |||
2037 | void init_vcpu(struct kvm_vcpu *vcpu) | ||
2038 | { | ||
2039 | int i; | ||
2040 | |||
2041 | vcpu->arch.mode_flags = GUEST_IN_PHY; | ||
2042 | VMX(vcpu, vrr[0]) = 0x38; | ||
2043 | VMX(vcpu, vrr[1]) = 0x38; | ||
2044 | VMX(vcpu, vrr[2]) = 0x38; | ||
2045 | VMX(vcpu, vrr[3]) = 0x38; | ||
2046 | VMX(vcpu, vrr[4]) = 0x38; | ||
2047 | VMX(vcpu, vrr[5]) = 0x38; | ||
2048 | VMX(vcpu, vrr[6]) = 0x38; | ||
2049 | VMX(vcpu, vrr[7]) = 0x38; | ||
2050 | VCPU(vcpu, vpsr) = IA64_PSR_BN; | ||
2051 | VCPU(vcpu, dcr) = 0; | ||
2052 | /* pta.size must not be 0. The minimum is 15 (32k) */ | ||
2053 | VCPU(vcpu, pta) = 15 << 2; | ||
2054 | VCPU(vcpu, itv) = 0x10000; | ||
2055 | VCPU(vcpu, itm) = 0; | ||
2056 | VMX(vcpu, last_itc) = 0; | ||
2057 | |||
2058 | VCPU(vcpu, lid) = VCPU_LID(vcpu); | ||
2059 | VCPU(vcpu, ivr) = 0; | ||
2060 | VCPU(vcpu, tpr) = 0x10000; | ||
2061 | VCPU(vcpu, eoi) = 0; | ||
2062 | VCPU(vcpu, irr[0]) = 0; | ||
2063 | VCPU(vcpu, irr[1]) = 0; | ||
2064 | VCPU(vcpu, irr[2]) = 0; | ||
2065 | VCPU(vcpu, irr[3]) = 0; | ||
2066 | VCPU(vcpu, pmv) = 0x10000; | ||
2067 | VCPU(vcpu, cmcv) = 0x10000; | ||
2068 | VCPU(vcpu, lrr0) = 0x10000; /* default reset value? */ | ||
2069 | VCPU(vcpu, lrr1) = 0x10000; /* default reset value? */ | ||
2070 | update_vhpi(vcpu, NULL_VECTOR); | ||
2071 | VLSAPIC_XTP(vcpu) = 0x80; /* disabled */ | ||
2072 | |||
2073 | for (i = 0; i < 4; i++) | ||
2074 | VLSAPIC_INSVC(vcpu, i) = 0; | ||
2075 | } | ||
2076 | |||
2077 | void kvm_init_all_rr(struct kvm_vcpu *vcpu) | ||
2078 | { | ||
2079 | unsigned long psr; | ||
2080 | |||
2081 | local_irq_save(psr); | ||
2082 | |||
2083 | /* WARNING: not allow co-exist of both virtual mode and physical | ||
2084 | * mode in same region | ||
2085 | */ | ||
2086 | |||
2087 | vcpu->arch.metaphysical_saved_rr0 = vrrtomrr(VMX(vcpu, vrr[VRN0])); | ||
2088 | vcpu->arch.metaphysical_saved_rr4 = vrrtomrr(VMX(vcpu, vrr[VRN4])); | ||
2089 | |||
2090 | if (is_physical_mode(vcpu)) { | ||
2091 | if (vcpu->arch.mode_flags & GUEST_PHY_EMUL) | ||
2092 | panic_vm(vcpu, "Machine Status conflicts!\n"); | ||
2093 | |||
2094 | ia64_set_rr((VRN0 << VRN_SHIFT), vcpu->arch.metaphysical_rr0); | ||
2095 | ia64_dv_serialize_data(); | ||
2096 | ia64_set_rr((VRN4 << VRN_SHIFT), vcpu->arch.metaphysical_rr4); | ||
2097 | ia64_dv_serialize_data(); | ||
2098 | } else { | ||
2099 | ia64_set_rr((VRN0 << VRN_SHIFT), | ||
2100 | vcpu->arch.metaphysical_saved_rr0); | ||
2101 | ia64_dv_serialize_data(); | ||
2102 | ia64_set_rr((VRN4 << VRN_SHIFT), | ||
2103 | vcpu->arch.metaphysical_saved_rr4); | ||
2104 | ia64_dv_serialize_data(); | ||
2105 | } | ||
2106 | ia64_set_rr((VRN1 << VRN_SHIFT), | ||
2107 | vrrtomrr(VMX(vcpu, vrr[VRN1]))); | ||
2108 | ia64_dv_serialize_data(); | ||
2109 | ia64_set_rr((VRN2 << VRN_SHIFT), | ||
2110 | vrrtomrr(VMX(vcpu, vrr[VRN2]))); | ||
2111 | ia64_dv_serialize_data(); | ||
2112 | ia64_set_rr((VRN3 << VRN_SHIFT), | ||
2113 | vrrtomrr(VMX(vcpu, vrr[VRN3]))); | ||
2114 | ia64_dv_serialize_data(); | ||
2115 | ia64_set_rr((VRN5 << VRN_SHIFT), | ||
2116 | vrrtomrr(VMX(vcpu, vrr[VRN5]))); | ||
2117 | ia64_dv_serialize_data(); | ||
2118 | ia64_set_rr((VRN7 << VRN_SHIFT), | ||
2119 | vrrtomrr(VMX(vcpu, vrr[VRN7]))); | ||
2120 | ia64_dv_serialize_data(); | ||
2121 | ia64_srlz_d(); | ||
2122 | ia64_set_psr(psr); | ||
2123 | } | ||
2124 | |||
2125 | int vmm_entry(void) | ||
2126 | { | ||
2127 | struct kvm_vcpu *v; | ||
2128 | v = current_vcpu; | ||
2129 | |||
2130 | ia64_call_vsa(PAL_VPS_RESTORE, (unsigned long)v->arch.vpd, | ||
2131 | 0, 0, 0, 0, 0, 0); | ||
2132 | kvm_init_vtlb(v); | ||
2133 | kvm_init_vhpt(v); | ||
2134 | init_vcpu(v); | ||
2135 | kvm_init_all_rr(v); | ||
2136 | vmm_reset_entry(); | ||
2137 | |||
2138 | return 0; | ||
2139 | } | ||
2140 | |||
2141 | static void kvm_show_registers(struct kvm_pt_regs *regs) | ||
2142 | { | ||
2143 | unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri; | ||
2144 | |||
2145 | struct kvm_vcpu *vcpu = current_vcpu; | ||
2146 | if (vcpu != NULL) | ||
2147 | printk("vcpu 0x%p vcpu %d\n", | ||
2148 | vcpu, vcpu->vcpu_id); | ||
2149 | |||
2150 | printk("psr : %016lx ifs : %016lx ip : [<%016lx>]\n", | ||
2151 | regs->cr_ipsr, regs->cr_ifs, ip); | ||
2152 | |||
2153 | printk("unat: %016lx pfs : %016lx rsc : %016lx\n", | ||
2154 | regs->ar_unat, regs->ar_pfs, regs->ar_rsc); | ||
2155 | printk("rnat: %016lx bspstore: %016lx pr : %016lx\n", | ||
2156 | regs->ar_rnat, regs->ar_bspstore, regs->pr); | ||
2157 | printk("ldrs: %016lx ccv : %016lx fpsr: %016lx\n", | ||
2158 | regs->loadrs, regs->ar_ccv, regs->ar_fpsr); | ||
2159 | printk("csd : %016lx ssd : %016lx\n", regs->ar_csd, regs->ar_ssd); | ||
2160 | printk("b0 : %016lx b6 : %016lx b7 : %016lx\n", regs->b0, | ||
2161 | regs->b6, regs->b7); | ||
2162 | printk("f6 : %05lx%016lx f7 : %05lx%016lx\n", | ||
2163 | regs->f6.u.bits[1], regs->f6.u.bits[0], | ||
2164 | regs->f7.u.bits[1], regs->f7.u.bits[0]); | ||
2165 | printk("f8 : %05lx%016lx f9 : %05lx%016lx\n", | ||
2166 | regs->f8.u.bits[1], regs->f8.u.bits[0], | ||
2167 | regs->f9.u.bits[1], regs->f9.u.bits[0]); | ||
2168 | printk("f10 : %05lx%016lx f11 : %05lx%016lx\n", | ||
2169 | regs->f10.u.bits[1], regs->f10.u.bits[0], | ||
2170 | regs->f11.u.bits[1], regs->f11.u.bits[0]); | ||
2171 | |||
2172 | printk("r1 : %016lx r2 : %016lx r3 : %016lx\n", regs->r1, | ||
2173 | regs->r2, regs->r3); | ||
2174 | printk("r8 : %016lx r9 : %016lx r10 : %016lx\n", regs->r8, | ||
2175 | regs->r9, regs->r10); | ||
2176 | printk("r11 : %016lx r12 : %016lx r13 : %016lx\n", regs->r11, | ||
2177 | regs->r12, regs->r13); | ||
2178 | printk("r14 : %016lx r15 : %016lx r16 : %016lx\n", regs->r14, | ||
2179 | regs->r15, regs->r16); | ||
2180 | printk("r17 : %016lx r18 : %016lx r19 : %016lx\n", regs->r17, | ||
2181 | regs->r18, regs->r19); | ||
2182 | printk("r20 : %016lx r21 : %016lx r22 : %016lx\n", regs->r20, | ||
2183 | regs->r21, regs->r22); | ||
2184 | printk("r23 : %016lx r24 : %016lx r25 : %016lx\n", regs->r23, | ||
2185 | regs->r24, regs->r25); | ||
2186 | printk("r26 : %016lx r27 : %016lx r28 : %016lx\n", regs->r26, | ||
2187 | regs->r27, regs->r28); | ||
2188 | printk("r29 : %016lx r30 : %016lx r31 : %016lx\n", regs->r29, | ||
2189 | regs->r30, regs->r31); | ||
2190 | |||
2191 | } | ||
2192 | |||
2193 | void panic_vm(struct kvm_vcpu *v, const char *fmt, ...) | ||
2194 | { | ||
2195 | va_list args; | ||
2196 | char buf[256]; | ||
2197 | |||
2198 | struct kvm_pt_regs *regs = vcpu_regs(v); | ||
2199 | struct exit_ctl_data *p = &v->arch.exit_data; | ||
2200 | va_start(args, fmt); | ||
2201 | vsnprintf(buf, sizeof(buf), fmt, args); | ||
2202 | va_end(args); | ||
2203 | printk(buf); | ||
2204 | kvm_show_registers(regs); | ||
2205 | p->exit_reason = EXIT_REASON_VM_PANIC; | ||
2206 | vmm_transition(v); | ||
2207 | /*Never to return*/ | ||
2208 | while (1); | ||
2209 | } | ||
diff --git a/arch/ia64/kvm/vcpu.h b/arch/ia64/kvm/vcpu.h deleted file mode 100644 index 988911b4cc7a..000000000000 --- a/arch/ia64/kvm/vcpu.h +++ /dev/null | |||
@@ -1,752 +0,0 @@ | |||
1 | /* | ||
2 | * vcpu.h: vcpu routines | ||
3 | * Copyright (c) 2005, Intel Corporation. | ||
4 | * Xuefei Xu (Anthony Xu) (Anthony.xu@intel.com) | ||
5 | * Yaozu Dong (Eddie Dong) (Eddie.dong@intel.com) | ||
6 | * | ||
7 | * Copyright (c) 2007, Intel Corporation. | ||
8 | * Xuefei Xu (Anthony Xu) (Anthony.xu@intel.com) | ||
9 | * Xiantao Zhang (xiantao.zhang@intel.com) | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms and conditions of the GNU General Public License, | ||
13 | * version 2, as published by the Free Software Foundation. | ||
14 | * | ||
15 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
16 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
18 | * more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License along with | ||
21 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | ||
22 | * Place - Suite 330, Boston, MA 02111-1307 USA. | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | |||
27 | #ifndef __KVM_VCPU_H__ | ||
28 | #define __KVM_VCPU_H__ | ||
29 | |||
30 | #include <asm/types.h> | ||
31 | #include <asm/fpu.h> | ||
32 | #include <asm/processor.h> | ||
33 | |||
34 | #ifndef __ASSEMBLY__ | ||
35 | #include "vti.h" | ||
36 | |||
37 | #include <linux/kvm_host.h> | ||
38 | #include <linux/spinlock.h> | ||
39 | |||
40 | typedef unsigned long IA64_INST; | ||
41 | |||
42 | typedef union U_IA64_BUNDLE { | ||
43 | unsigned long i64[2]; | ||
44 | struct { unsigned long template:5, slot0:41, slot1a:18, | ||
45 | slot1b:23, slot2:41; }; | ||
46 | /* NOTE: following doesn't work because bitfields can't cross natural | ||
47 | size boundaries | ||
48 | struct { unsigned long template:5, slot0:41, slot1:41, slot2:41; }; */ | ||
49 | } IA64_BUNDLE; | ||
50 | |||
51 | typedef union U_INST64_A5 { | ||
52 | IA64_INST inst; | ||
53 | struct { unsigned long qp:6, r1:7, imm7b:7, r3:2, imm5c:5, | ||
54 | imm9d:9, s:1, major:4; }; | ||
55 | } INST64_A5; | ||
56 | |||
57 | typedef union U_INST64_B4 { | ||
58 | IA64_INST inst; | ||
59 | struct { unsigned long qp:6, btype:3, un3:3, p:1, b2:3, un11:11, x6:6, | ||
60 | wh:2, d:1, un1:1, major:4; }; | ||
61 | } INST64_B4; | ||
62 | |||
63 | typedef union U_INST64_B8 { | ||
64 | IA64_INST inst; | ||
65 | struct { unsigned long qp:6, un21:21, x6:6, un4:4, major:4; }; | ||
66 | } INST64_B8; | ||
67 | |||
68 | typedef union U_INST64_B9 { | ||
69 | IA64_INST inst; | ||
70 | struct { unsigned long qp:6, imm20:20, :1, x6:6, :3, i:1, major:4; }; | ||
71 | } INST64_B9; | ||
72 | |||
73 | typedef union U_INST64_I19 { | ||
74 | IA64_INST inst; | ||
75 | struct { unsigned long qp:6, imm20:20, :1, x6:6, x3:3, i:1, major:4; }; | ||
76 | } INST64_I19; | ||
77 | |||
78 | typedef union U_INST64_I26 { | ||
79 | IA64_INST inst; | ||
80 | struct { unsigned long qp:6, :7, r2:7, ar3:7, x6:6, x3:3, :1, major:4; }; | ||
81 | } INST64_I26; | ||
82 | |||
83 | typedef union U_INST64_I27 { | ||
84 | IA64_INST inst; | ||
85 | struct { unsigned long qp:6, :7, imm:7, ar3:7, x6:6, x3:3, s:1, major:4; }; | ||
86 | } INST64_I27; | ||
87 | |||
88 | typedef union U_INST64_I28 { /* not privileged (mov from AR) */ | ||
89 | IA64_INST inst; | ||
90 | struct { unsigned long qp:6, r1:7, :7, ar3:7, x6:6, x3:3, :1, major:4; }; | ||
91 | } INST64_I28; | ||
92 | |||
93 | typedef union U_INST64_M28 { | ||
94 | IA64_INST inst; | ||
95 | struct { unsigned long qp:6, :14, r3:7, x6:6, x3:3, :1, major:4; }; | ||
96 | } INST64_M28; | ||
97 | |||
98 | typedef union U_INST64_M29 { | ||
99 | IA64_INST inst; | ||
100 | struct { unsigned long qp:6, :7, r2:7, ar3:7, x6:6, x3:3, :1, major:4; }; | ||
101 | } INST64_M29; | ||
102 | |||
103 | typedef union U_INST64_M30 { | ||
104 | IA64_INST inst; | ||
105 | struct { unsigned long qp:6, :7, imm:7, ar3:7, x4:4, x2:2, | ||
106 | x3:3, s:1, major:4; }; | ||
107 | } INST64_M30; | ||
108 | |||
109 | typedef union U_INST64_M31 { | ||
110 | IA64_INST inst; | ||
111 | struct { unsigned long qp:6, r1:7, :7, ar3:7, x6:6, x3:3, :1, major:4; }; | ||
112 | } INST64_M31; | ||
113 | |||
114 | typedef union U_INST64_M32 { | ||
115 | IA64_INST inst; | ||
116 | struct { unsigned long qp:6, :7, r2:7, cr3:7, x6:6, x3:3, :1, major:4; }; | ||
117 | } INST64_M32; | ||
118 | |||
119 | typedef union U_INST64_M33 { | ||
120 | IA64_INST inst; | ||
121 | struct { unsigned long qp:6, r1:7, :7, cr3:7, x6:6, x3:3, :1, major:4; }; | ||
122 | } INST64_M33; | ||
123 | |||
124 | typedef union U_INST64_M35 { | ||
125 | IA64_INST inst; | ||
126 | struct { unsigned long qp:6, :7, r2:7, :7, x6:6, x3:3, :1, major:4; }; | ||
127 | |||
128 | } INST64_M35; | ||
129 | |||
130 | typedef union U_INST64_M36 { | ||
131 | IA64_INST inst; | ||
132 | struct { unsigned long qp:6, r1:7, :14, x6:6, x3:3, :1, major:4; }; | ||
133 | } INST64_M36; | ||
134 | |||
135 | typedef union U_INST64_M37 { | ||
136 | IA64_INST inst; | ||
137 | struct { unsigned long qp:6, imm20a:20, :1, x4:4, x2:2, x3:3, | ||
138 | i:1, major:4; }; | ||
139 | } INST64_M37; | ||
140 | |||
141 | typedef union U_INST64_M41 { | ||
142 | IA64_INST inst; | ||
143 | struct { unsigned long qp:6, :7, r2:7, :7, x6:6, x3:3, :1, major:4; }; | ||
144 | } INST64_M41; | ||
145 | |||
146 | typedef union U_INST64_M42 { | ||
147 | IA64_INST inst; | ||
148 | struct { unsigned long qp:6, :7, r2:7, r3:7, x6:6, x3:3, :1, major:4; }; | ||
149 | } INST64_M42; | ||
150 | |||
151 | typedef union U_INST64_M43 { | ||
152 | IA64_INST inst; | ||
153 | struct { unsigned long qp:6, r1:7, :7, r3:7, x6:6, x3:3, :1, major:4; }; | ||
154 | } INST64_M43; | ||
155 | |||
156 | typedef union U_INST64_M44 { | ||
157 | IA64_INST inst; | ||
158 | struct { unsigned long qp:6, imm:21, x4:4, i2:2, x3:3, i:1, major:4; }; | ||
159 | } INST64_M44; | ||
160 | |||
161 | typedef union U_INST64_M45 { | ||
162 | IA64_INST inst; | ||
163 | struct { unsigned long qp:6, :7, r2:7, r3:7, x6:6, x3:3, :1, major:4; }; | ||
164 | } INST64_M45; | ||
165 | |||
166 | typedef union U_INST64_M46 { | ||
167 | IA64_INST inst; | ||
168 | struct { unsigned long qp:6, r1:7, un7:7, r3:7, x6:6, | ||
169 | x3:3, un1:1, major:4; }; | ||
170 | } INST64_M46; | ||
171 | |||
172 | typedef union U_INST64_M47 { | ||
173 | IA64_INST inst; | ||
174 | struct { unsigned long qp:6, un14:14, r3:7, x6:6, x3:3, un1:1, major:4; }; | ||
175 | } INST64_M47; | ||
176 | |||
177 | typedef union U_INST64_M1{ | ||
178 | IA64_INST inst; | ||
179 | struct { unsigned long qp:6, r1:7, un7:7, r3:7, x:1, hint:2, | ||
180 | x6:6, m:1, major:4; }; | ||
181 | } INST64_M1; | ||
182 | |||
183 | typedef union U_INST64_M2{ | ||
184 | IA64_INST inst; | ||
185 | struct { unsigned long qp:6, r1:7, r2:7, r3:7, x:1, hint:2, | ||
186 | x6:6, m:1, major:4; }; | ||
187 | } INST64_M2; | ||
188 | |||
189 | typedef union U_INST64_M3{ | ||
190 | IA64_INST inst; | ||
191 | struct { unsigned long qp:6, r1:7, imm7:7, r3:7, i:1, hint:2, | ||
192 | x6:6, s:1, major:4; }; | ||
193 | } INST64_M3; | ||
194 | |||
195 | typedef union U_INST64_M4 { | ||
196 | IA64_INST inst; | ||
197 | struct { unsigned long qp:6, un7:7, r2:7, r3:7, x:1, hint:2, | ||
198 | x6:6, m:1, major:4; }; | ||
199 | } INST64_M4; | ||
200 | |||
201 | typedef union U_INST64_M5 { | ||
202 | IA64_INST inst; | ||
203 | struct { unsigned long qp:6, imm7:7, r2:7, r3:7, i:1, hint:2, | ||
204 | x6:6, s:1, major:4; }; | ||
205 | } INST64_M5; | ||
206 | |||
207 | typedef union U_INST64_M6 { | ||
208 | IA64_INST inst; | ||
209 | struct { unsigned long qp:6, f1:7, un7:7, r3:7, x:1, hint:2, | ||
210 | x6:6, m:1, major:4; }; | ||
211 | } INST64_M6; | ||
212 | |||
213 | typedef union U_INST64_M9 { | ||
214 | IA64_INST inst; | ||
215 | struct { unsigned long qp:6, :7, f2:7, r3:7, x:1, hint:2, | ||
216 | x6:6, m:1, major:4; }; | ||
217 | } INST64_M9; | ||
218 | |||
219 | typedef union U_INST64_M10 { | ||
220 | IA64_INST inst; | ||
221 | struct { unsigned long qp:6, imm7:7, f2:7, r3:7, i:1, hint:2, | ||
222 | x6:6, s:1, major:4; }; | ||
223 | } INST64_M10; | ||
224 | |||
225 | typedef union U_INST64_M12 { | ||
226 | IA64_INST inst; | ||
227 | struct { unsigned long qp:6, f1:7, f2:7, r3:7, x:1, hint:2, | ||
228 | x6:6, m:1, major:4; }; | ||
229 | } INST64_M12; | ||
230 | |||
231 | typedef union U_INST64_M15 { | ||
232 | IA64_INST inst; | ||
233 | struct { unsigned long qp:6, :7, imm7:7, r3:7, i:1, hint:2, | ||
234 | x6:6, s:1, major:4; }; | ||
235 | } INST64_M15; | ||
236 | |||
237 | typedef union U_INST64 { | ||
238 | IA64_INST inst; | ||
239 | struct { unsigned long :37, major:4; } generic; | ||
240 | INST64_A5 A5; /* used in build_hypercall_bundle only */ | ||
241 | INST64_B4 B4; /* used in build_hypercall_bundle only */ | ||
242 | INST64_B8 B8; /* rfi, bsw.[01] */ | ||
243 | INST64_B9 B9; /* break.b */ | ||
244 | INST64_I19 I19; /* used in build_hypercall_bundle only */ | ||
245 | INST64_I26 I26; /* mov register to ar (I unit) */ | ||
246 | INST64_I27 I27; /* mov immediate to ar (I unit) */ | ||
247 | INST64_I28 I28; /* mov from ar (I unit) */ | ||
248 | INST64_M1 M1; /* ld integer */ | ||
249 | INST64_M2 M2; | ||
250 | INST64_M3 M3; | ||
251 | INST64_M4 M4; /* st integer */ | ||
252 | INST64_M5 M5; | ||
253 | INST64_M6 M6; /* ldfd floating pointer */ | ||
254 | INST64_M9 M9; /* stfd floating pointer */ | ||
255 | INST64_M10 M10; /* stfd floating pointer */ | ||
256 | INST64_M12 M12; /* ldfd pair floating pointer */ | ||
257 | INST64_M15 M15; /* lfetch + imm update */ | ||
258 | INST64_M28 M28; /* purge translation cache entry */ | ||
259 | INST64_M29 M29; /* mov register to ar (M unit) */ | ||
260 | INST64_M30 M30; /* mov immediate to ar (M unit) */ | ||
261 | INST64_M31 M31; /* mov from ar (M unit) */ | ||
262 | INST64_M32 M32; /* mov reg to cr */ | ||
263 | INST64_M33 M33; /* mov from cr */ | ||
264 | INST64_M35 M35; /* mov to psr */ | ||
265 | INST64_M36 M36; /* mov from psr */ | ||
266 | INST64_M37 M37; /* break.m */ | ||
267 | INST64_M41 M41; /* translation cache insert */ | ||
268 | INST64_M42 M42; /* mov to indirect reg/translation reg insert*/ | ||
269 | INST64_M43 M43; /* mov from indirect reg */ | ||
270 | INST64_M44 M44; /* set/reset system mask */ | ||
271 | INST64_M45 M45; /* translation purge */ | ||
272 | INST64_M46 M46; /* translation access (tpa,tak) */ | ||
273 | INST64_M47 M47; /* purge translation entry */ | ||
274 | } INST64; | ||
275 | |||
276 | #define MASK_41 ((unsigned long)0x1ffffffffff) | ||
277 | |||
278 | /* Virtual address memory attributes encoding */ | ||
279 | #define VA_MATTR_WB 0x0 | ||
280 | #define VA_MATTR_UC 0x4 | ||
281 | #define VA_MATTR_UCE 0x5 | ||
282 | #define VA_MATTR_WC 0x6 | ||
283 | #define VA_MATTR_NATPAGE 0x7 | ||
284 | |||
285 | #define PMASK(size) (~((size) - 1)) | ||
286 | #define PSIZE(size) (1UL<<(size)) | ||
287 | #define CLEARLSB(ppn, nbits) (((ppn) >> (nbits)) << (nbits)) | ||
288 | #define PAGEALIGN(va, ps) CLEARLSB(va, ps) | ||
289 | #define PAGE_FLAGS_RV_MASK (0x2|(0x3UL<<50)|(((1UL<<11)-1)<<53)) | ||
290 | #define _PAGE_MA_ST (0x1 << 2) /* is reserved for software use */ | ||
291 | |||
292 | #define ARCH_PAGE_SHIFT 12 | ||
293 | |||
294 | #define INVALID_TI_TAG (1UL << 63) | ||
295 | |||
296 | #define VTLB_PTE_P_BIT 0 | ||
297 | #define VTLB_PTE_IO_BIT 60 | ||
298 | #define VTLB_PTE_IO (1UL<<VTLB_PTE_IO_BIT) | ||
299 | #define VTLB_PTE_P (1UL<<VTLB_PTE_P_BIT) | ||
300 | |||
301 | #define vcpu_quick_region_check(_tr_regions,_ifa) \ | ||
302 | (_tr_regions & (1 << ((unsigned long)_ifa >> 61))) | ||
303 | |||
304 | #define vcpu_quick_region_set(_tr_regions,_ifa) \ | ||
305 | do {_tr_regions |= (1 << ((unsigned long)_ifa >> 61)); } while (0) | ||
306 | |||
307 | static inline void vcpu_set_tr(struct thash_data *trp, u64 pte, u64 itir, | ||
308 | u64 va, u64 rid) | ||
309 | { | ||
310 | trp->page_flags = pte; | ||
311 | trp->itir = itir; | ||
312 | trp->vadr = va; | ||
313 | trp->rid = rid; | ||
314 | } | ||
315 | |||
316 | extern u64 kvm_get_mpt_entry(u64 gpfn); | ||
317 | |||
318 | /* Return I/ */ | ||
319 | static inline u64 __gpfn_is_io(u64 gpfn) | ||
320 | { | ||
321 | u64 pte; | ||
322 | pte = kvm_get_mpt_entry(gpfn); | ||
323 | if (!(pte & GPFN_INV_MASK)) { | ||
324 | pte = pte & GPFN_IO_MASK; | ||
325 | if (pte != GPFN_PHYS_MMIO) | ||
326 | return pte; | ||
327 | } | ||
328 | return 0; | ||
329 | } | ||
330 | #endif | ||
331 | #define IA64_NO_FAULT 0 | ||
332 | #define IA64_FAULT 1 | ||
333 | |||
334 | #define VMM_RBS_OFFSET ((VMM_TASK_SIZE + 15) & ~15) | ||
335 | |||
336 | #define SW_BAD 0 /* Bad mode transitition */ | ||
337 | #define SW_V2P 1 /* Physical emulatino is activated */ | ||
338 | #define SW_P2V 2 /* Exit physical mode emulation */ | ||
339 | #define SW_SELF 3 /* No mode transition */ | ||
340 | #define SW_NOP 4 /* Mode transition, but without action required */ | ||
341 | |||
342 | #define GUEST_IN_PHY 0x1 | ||
343 | #define GUEST_PHY_EMUL 0x2 | ||
344 | |||
345 | #define current_vcpu ((struct kvm_vcpu *) ia64_getreg(_IA64_REG_TP)) | ||
346 | |||
347 | #define VRN_SHIFT 61 | ||
348 | #define VRN_MASK 0xe000000000000000 | ||
349 | #define VRN0 0x0UL | ||
350 | #define VRN1 0x1UL | ||
351 | #define VRN2 0x2UL | ||
352 | #define VRN3 0x3UL | ||
353 | #define VRN4 0x4UL | ||
354 | #define VRN5 0x5UL | ||
355 | #define VRN6 0x6UL | ||
356 | #define VRN7 0x7UL | ||
357 | |||
358 | #define IRQ_NO_MASKED 0 | ||
359 | #define IRQ_MASKED_BY_VTPR 1 | ||
360 | #define IRQ_MASKED_BY_INSVC 2 /* masked by inservice IRQ */ | ||
361 | |||
362 | #define PTA_BASE_SHIFT 15 | ||
363 | |||
364 | #define IA64_PSR_VM_BIT 46 | ||
365 | #define IA64_PSR_VM (__IA64_UL(1) << IA64_PSR_VM_BIT) | ||
366 | |||
367 | /* Interruption Function State */ | ||
368 | #define IA64_IFS_V_BIT 63 | ||
369 | #define IA64_IFS_V (__IA64_UL(1) << IA64_IFS_V_BIT) | ||
370 | |||
371 | #define PHY_PAGE_UC (_PAGE_A|_PAGE_D|_PAGE_P|_PAGE_MA_UC|_PAGE_AR_RWX) | ||
372 | #define PHY_PAGE_WB (_PAGE_A|_PAGE_D|_PAGE_P|_PAGE_MA_WB|_PAGE_AR_RWX) | ||
373 | |||
374 | #ifndef __ASSEMBLY__ | ||
375 | |||
376 | #include <asm/gcc_intrin.h> | ||
377 | |||
378 | #define is_physical_mode(v) \ | ||
379 | ((v->arch.mode_flags) & GUEST_IN_PHY) | ||
380 | |||
381 | #define is_virtual_mode(v) \ | ||
382 | (!is_physical_mode(v)) | ||
383 | |||
384 | #define MODE_IND(psr) \ | ||
385 | (((psr).it << 2) + ((psr).dt << 1) + (psr).rt) | ||
386 | |||
387 | #ifndef CONFIG_SMP | ||
388 | #define _vmm_raw_spin_lock(x) do {}while(0) | ||
389 | #define _vmm_raw_spin_unlock(x) do {}while(0) | ||
390 | #else | ||
391 | typedef struct { | ||
392 | volatile unsigned int lock; | ||
393 | } vmm_spinlock_t; | ||
394 | #define _vmm_raw_spin_lock(x) \ | ||
395 | do { \ | ||
396 | __u32 *ia64_spinlock_ptr = (__u32 *) (x); \ | ||
397 | __u64 ia64_spinlock_val; \ | ||
398 | ia64_spinlock_val = ia64_cmpxchg4_acq(ia64_spinlock_ptr, 1, 0);\ | ||
399 | if (unlikely(ia64_spinlock_val)) { \ | ||
400 | do { \ | ||
401 | while (*ia64_spinlock_ptr) \ | ||
402 | ia64_barrier(); \ | ||
403 | ia64_spinlock_val = \ | ||
404 | ia64_cmpxchg4_acq(ia64_spinlock_ptr, 1, 0);\ | ||
405 | } while (ia64_spinlock_val); \ | ||
406 | } \ | ||
407 | } while (0) | ||
408 | |||
409 | #define _vmm_raw_spin_unlock(x) \ | ||
410 | do { barrier(); \ | ||
411 | ((vmm_spinlock_t *)x)->lock = 0; } \ | ||
412 | while (0) | ||
413 | #endif | ||
414 | |||
415 | void vmm_spin_lock(vmm_spinlock_t *lock); | ||
416 | void vmm_spin_unlock(vmm_spinlock_t *lock); | ||
417 | enum { | ||
418 | I_TLB = 1, | ||
419 | D_TLB = 2 | ||
420 | }; | ||
421 | |||
422 | union kvm_va { | ||
423 | struct { | ||
424 | unsigned long off : 60; /* intra-region offset */ | ||
425 | unsigned long reg : 4; /* region number */ | ||
426 | } f; | ||
427 | unsigned long l; | ||
428 | void *p; | ||
429 | }; | ||
430 | |||
431 | #define __kvm_pa(x) ({union kvm_va _v; _v.l = (long) (x); \ | ||
432 | _v.f.reg = 0; _v.l; }) | ||
433 | #define __kvm_va(x) ({union kvm_va _v; _v.l = (long) (x); \ | ||
434 | _v.f.reg = -1; _v.p; }) | ||
435 | |||
436 | #define _REGION_ID(x) ({union ia64_rr _v; _v.val = (long)(x); \ | ||
437 | _v.rid; }) | ||
438 | #define _REGION_PAGE_SIZE(x) ({union ia64_rr _v; _v.val = (long)(x); \ | ||
439 | _v.ps; }) | ||
440 | #define _REGION_HW_WALKER(x) ({union ia64_rr _v; _v.val = (long)(x); \ | ||
441 | _v.ve; }) | ||
442 | |||
443 | enum vhpt_ref{ DATA_REF, NA_REF, INST_REF, RSE_REF }; | ||
444 | enum tlb_miss_type { INSTRUCTION, DATA, REGISTER }; | ||
445 | |||
446 | #define VCPU(_v, _x) ((_v)->arch.vpd->_x) | ||
447 | #define VMX(_v, _x) ((_v)->arch._x) | ||
448 | |||
449 | #define VLSAPIC_INSVC(vcpu, i) ((vcpu)->arch.insvc[i]) | ||
450 | #define VLSAPIC_XTP(_v) VMX(_v, xtp) | ||
451 | |||
452 | static inline unsigned long itir_ps(unsigned long itir) | ||
453 | { | ||
454 | return ((itir >> 2) & 0x3f); | ||
455 | } | ||
456 | |||
457 | |||
458 | /************************************************************************** | ||
459 | VCPU control register access routines | ||
460 | **************************************************************************/ | ||
461 | |||
462 | static inline u64 vcpu_get_itir(struct kvm_vcpu *vcpu) | ||
463 | { | ||
464 | return ((u64)VCPU(vcpu, itir)); | ||
465 | } | ||
466 | |||
467 | static inline void vcpu_set_itir(struct kvm_vcpu *vcpu, u64 val) | ||
468 | { | ||
469 | VCPU(vcpu, itir) = val; | ||
470 | } | ||
471 | |||
472 | static inline u64 vcpu_get_ifa(struct kvm_vcpu *vcpu) | ||
473 | { | ||
474 | return ((u64)VCPU(vcpu, ifa)); | ||
475 | } | ||
476 | |||
477 | static inline void vcpu_set_ifa(struct kvm_vcpu *vcpu, u64 val) | ||
478 | { | ||
479 | VCPU(vcpu, ifa) = val; | ||
480 | } | ||
481 | |||
482 | static inline u64 vcpu_get_iva(struct kvm_vcpu *vcpu) | ||
483 | { | ||
484 | return ((u64)VCPU(vcpu, iva)); | ||
485 | } | ||
486 | |||
487 | static inline u64 vcpu_get_pta(struct kvm_vcpu *vcpu) | ||
488 | { | ||
489 | return ((u64)VCPU(vcpu, pta)); | ||
490 | } | ||
491 | |||
492 | static inline u64 vcpu_get_lid(struct kvm_vcpu *vcpu) | ||
493 | { | ||
494 | return ((u64)VCPU(vcpu, lid)); | ||
495 | } | ||
496 | |||
497 | static inline u64 vcpu_get_tpr(struct kvm_vcpu *vcpu) | ||
498 | { | ||
499 | return ((u64)VCPU(vcpu, tpr)); | ||
500 | } | ||
501 | |||
502 | static inline u64 vcpu_get_eoi(struct kvm_vcpu *vcpu) | ||
503 | { | ||
504 | return (0UL); /*reads of eoi always return 0 */ | ||
505 | } | ||
506 | |||
507 | static inline u64 vcpu_get_irr0(struct kvm_vcpu *vcpu) | ||
508 | { | ||
509 | return ((u64)VCPU(vcpu, irr[0])); | ||
510 | } | ||
511 | |||
512 | static inline u64 vcpu_get_irr1(struct kvm_vcpu *vcpu) | ||
513 | { | ||
514 | return ((u64)VCPU(vcpu, irr[1])); | ||
515 | } | ||
516 | |||
517 | static inline u64 vcpu_get_irr2(struct kvm_vcpu *vcpu) | ||
518 | { | ||
519 | return ((u64)VCPU(vcpu, irr[2])); | ||
520 | } | ||
521 | |||
522 | static inline u64 vcpu_get_irr3(struct kvm_vcpu *vcpu) | ||
523 | { | ||
524 | return ((u64)VCPU(vcpu, irr[3])); | ||
525 | } | ||
526 | |||
527 | static inline void vcpu_set_dcr(struct kvm_vcpu *vcpu, u64 val) | ||
528 | { | ||
529 | ia64_setreg(_IA64_REG_CR_DCR, val); | ||
530 | } | ||
531 | |||
532 | static inline void vcpu_set_isr(struct kvm_vcpu *vcpu, u64 val) | ||
533 | { | ||
534 | VCPU(vcpu, isr) = val; | ||
535 | } | ||
536 | |||
537 | static inline void vcpu_set_lid(struct kvm_vcpu *vcpu, u64 val) | ||
538 | { | ||
539 | VCPU(vcpu, lid) = val; | ||
540 | } | ||
541 | |||
542 | static inline void vcpu_set_ipsr(struct kvm_vcpu *vcpu, u64 val) | ||
543 | { | ||
544 | VCPU(vcpu, ipsr) = val; | ||
545 | } | ||
546 | |||
547 | static inline void vcpu_set_iip(struct kvm_vcpu *vcpu, u64 val) | ||
548 | { | ||
549 | VCPU(vcpu, iip) = val; | ||
550 | } | ||
551 | |||
552 | static inline void vcpu_set_ifs(struct kvm_vcpu *vcpu, u64 val) | ||
553 | { | ||
554 | VCPU(vcpu, ifs) = val; | ||
555 | } | ||
556 | |||
557 | static inline void vcpu_set_iipa(struct kvm_vcpu *vcpu, u64 val) | ||
558 | { | ||
559 | VCPU(vcpu, iipa) = val; | ||
560 | } | ||
561 | |||
562 | static inline void vcpu_set_iha(struct kvm_vcpu *vcpu, u64 val) | ||
563 | { | ||
564 | VCPU(vcpu, iha) = val; | ||
565 | } | ||
566 | |||
567 | |||
568 | static inline u64 vcpu_get_rr(struct kvm_vcpu *vcpu, u64 reg) | ||
569 | { | ||
570 | return vcpu->arch.vrr[reg>>61]; | ||
571 | } | ||
572 | |||
573 | /************************************************************************** | ||
574 | VCPU debug breakpoint register access routines | ||
575 | **************************************************************************/ | ||
576 | |||
577 | static inline void vcpu_set_dbr(struct kvm_vcpu *vcpu, u64 reg, u64 val) | ||
578 | { | ||
579 | __ia64_set_dbr(reg, val); | ||
580 | } | ||
581 | |||
582 | static inline void vcpu_set_ibr(struct kvm_vcpu *vcpu, u64 reg, u64 val) | ||
583 | { | ||
584 | ia64_set_ibr(reg, val); | ||
585 | } | ||
586 | |||
587 | static inline u64 vcpu_get_dbr(struct kvm_vcpu *vcpu, u64 reg) | ||
588 | { | ||
589 | return ((u64)__ia64_get_dbr(reg)); | ||
590 | } | ||
591 | |||
592 | static inline u64 vcpu_get_ibr(struct kvm_vcpu *vcpu, u64 reg) | ||
593 | { | ||
594 | return ((u64)ia64_get_ibr(reg)); | ||
595 | } | ||
596 | |||
597 | /************************************************************************** | ||
598 | VCPU performance monitor register access routines | ||
599 | **************************************************************************/ | ||
600 | static inline void vcpu_set_pmc(struct kvm_vcpu *vcpu, u64 reg, u64 val) | ||
601 | { | ||
602 | /* NOTE: Writes to unimplemented PMC registers are discarded */ | ||
603 | ia64_set_pmc(reg, val); | ||
604 | } | ||
605 | |||
606 | static inline void vcpu_set_pmd(struct kvm_vcpu *vcpu, u64 reg, u64 val) | ||
607 | { | ||
608 | /* NOTE: Writes to unimplemented PMD registers are discarded */ | ||
609 | ia64_set_pmd(reg, val); | ||
610 | } | ||
611 | |||
612 | static inline u64 vcpu_get_pmc(struct kvm_vcpu *vcpu, u64 reg) | ||
613 | { | ||
614 | /* NOTE: Reads from unimplemented PMC registers return zero */ | ||
615 | return ((u64)ia64_get_pmc(reg)); | ||
616 | } | ||
617 | |||
618 | static inline u64 vcpu_get_pmd(struct kvm_vcpu *vcpu, u64 reg) | ||
619 | { | ||
620 | /* NOTE: Reads from unimplemented PMD registers return zero */ | ||
621 | return ((u64)ia64_get_pmd(reg)); | ||
622 | } | ||
623 | |||
624 | static inline unsigned long vrrtomrr(unsigned long val) | ||
625 | { | ||
626 | union ia64_rr rr; | ||
627 | rr.val = val; | ||
628 | rr.rid = (rr.rid << 4) | 0xe; | ||
629 | if (rr.ps > PAGE_SHIFT) | ||
630 | rr.ps = PAGE_SHIFT; | ||
631 | rr.ve = 1; | ||
632 | return rr.val; | ||
633 | } | ||
634 | |||
635 | |||
636 | static inline int highest_bits(int *dat) | ||
637 | { | ||
638 | u32 bits, bitnum; | ||
639 | int i; | ||
640 | |||
641 | /* loop for all 256 bits */ | ||
642 | for (i = 7; i >= 0 ; i--) { | ||
643 | bits = dat[i]; | ||
644 | if (bits) { | ||
645 | bitnum = fls(bits); | ||
646 | return i * 32 + bitnum - 1; | ||
647 | } | ||
648 | } | ||
649 | return NULL_VECTOR; | ||
650 | } | ||
651 | |||
652 | /* | ||
653 | * The pending irq is higher than the inservice one. | ||
654 | * | ||
655 | */ | ||
656 | static inline int is_higher_irq(int pending, int inservice) | ||
657 | { | ||
658 | return ((pending > inservice) | ||
659 | || ((pending != NULL_VECTOR) | ||
660 | && (inservice == NULL_VECTOR))); | ||
661 | } | ||
662 | |||
663 | static inline int is_higher_class(int pending, int mic) | ||
664 | { | ||
665 | return ((pending >> 4) > mic); | ||
666 | } | ||
667 | |||
668 | /* | ||
669 | * Return 0-255 for pending irq. | ||
670 | * NULL_VECTOR: when no pending. | ||
671 | */ | ||
672 | static inline int highest_pending_irq(struct kvm_vcpu *vcpu) | ||
673 | { | ||
674 | if (VCPU(vcpu, irr[0]) & (1UL<<NMI_VECTOR)) | ||
675 | return NMI_VECTOR; | ||
676 | if (VCPU(vcpu, irr[0]) & (1UL<<ExtINT_VECTOR)) | ||
677 | return ExtINT_VECTOR; | ||
678 | |||
679 | return highest_bits((int *)&VCPU(vcpu, irr[0])); | ||
680 | } | ||
681 | |||
682 | static inline int highest_inservice_irq(struct kvm_vcpu *vcpu) | ||
683 | { | ||
684 | if (VMX(vcpu, insvc[0]) & (1UL<<NMI_VECTOR)) | ||
685 | return NMI_VECTOR; | ||
686 | if (VMX(vcpu, insvc[0]) & (1UL<<ExtINT_VECTOR)) | ||
687 | return ExtINT_VECTOR; | ||
688 | |||
689 | return highest_bits((int *)&(VMX(vcpu, insvc[0]))); | ||
690 | } | ||
691 | |||
692 | extern void vcpu_get_fpreg(struct kvm_vcpu *vcpu, unsigned long reg, | ||
693 | struct ia64_fpreg *val); | ||
694 | extern void vcpu_set_fpreg(struct kvm_vcpu *vcpu, unsigned long reg, | ||
695 | struct ia64_fpreg *val); | ||
696 | extern u64 vcpu_get_gr(struct kvm_vcpu *vcpu, unsigned long reg); | ||
697 | extern void vcpu_set_gr(struct kvm_vcpu *vcpu, unsigned long reg, | ||
698 | u64 val, int nat); | ||
699 | extern unsigned long vcpu_get_psr(struct kvm_vcpu *vcpu); | ||
700 | extern void vcpu_set_psr(struct kvm_vcpu *vcpu, unsigned long val); | ||
701 | extern u64 vcpu_thash(struct kvm_vcpu *vcpu, u64 vadr); | ||
702 | extern void vcpu_bsw0(struct kvm_vcpu *vcpu); | ||
703 | extern void thash_vhpt_insert(struct kvm_vcpu *v, u64 pte, | ||
704 | u64 itir, u64 va, int type); | ||
705 | extern struct thash_data *vhpt_lookup(u64 va); | ||
706 | extern u64 guest_vhpt_lookup(u64 iha, u64 *pte); | ||
707 | extern void thash_purge_entries(struct kvm_vcpu *v, u64 va, u64 ps); | ||
708 | extern void thash_purge_entries_remote(struct kvm_vcpu *v, u64 va, u64 ps); | ||
709 | extern u64 translate_phy_pte(u64 *pte, u64 itir, u64 va); | ||
710 | extern void thash_purge_and_insert(struct kvm_vcpu *v, u64 pte, | ||
711 | u64 itir, u64 ifa, int type); | ||
712 | extern void thash_purge_all(struct kvm_vcpu *v); | ||
713 | extern struct thash_data *vtlb_lookup(struct kvm_vcpu *v, | ||
714 | u64 va, int is_data); | ||
715 | extern int vtr_find_overlap(struct kvm_vcpu *vcpu, u64 va, | ||
716 | u64 ps, int is_data); | ||
717 | |||
718 | extern void vcpu_increment_iip(struct kvm_vcpu *v); | ||
719 | extern void vcpu_decrement_iip(struct kvm_vcpu *vcpu); | ||
720 | extern void vcpu_pend_interrupt(struct kvm_vcpu *vcpu, u8 vec); | ||
721 | extern void vcpu_unpend_interrupt(struct kvm_vcpu *vcpu, u8 vec); | ||
722 | extern void data_page_not_present(struct kvm_vcpu *vcpu, u64 vadr); | ||
723 | extern void dnat_page_consumption(struct kvm_vcpu *vcpu, u64 vadr); | ||
724 | extern void alt_dtlb(struct kvm_vcpu *vcpu, u64 vadr); | ||
725 | extern void nested_dtlb(struct kvm_vcpu *vcpu); | ||
726 | extern void dvhpt_fault(struct kvm_vcpu *vcpu, u64 vadr); | ||
727 | extern int vhpt_enabled(struct kvm_vcpu *vcpu, u64 vadr, enum vhpt_ref ref); | ||
728 | |||
729 | extern void update_vhpi(struct kvm_vcpu *vcpu, int vec); | ||
730 | extern int irq_masked(struct kvm_vcpu *vcpu, int h_pending, int h_inservice); | ||
731 | |||
732 | extern int fetch_code(struct kvm_vcpu *vcpu, u64 gip, IA64_BUNDLE *pbundle); | ||
733 | extern void emulate_io_inst(struct kvm_vcpu *vcpu, u64 padr, u64 ma); | ||
734 | extern void vmm_transition(struct kvm_vcpu *vcpu); | ||
735 | extern void vmm_trampoline(union context *from, union context *to); | ||
736 | extern int vmm_entry(void); | ||
737 | extern u64 vcpu_get_itc(struct kvm_vcpu *vcpu); | ||
738 | |||
739 | extern void vmm_reset_entry(void); | ||
740 | void kvm_init_vtlb(struct kvm_vcpu *v); | ||
741 | void kvm_init_vhpt(struct kvm_vcpu *v); | ||
742 | void thash_init(struct thash_cb *hcb, u64 sz); | ||
743 | |||
744 | void panic_vm(struct kvm_vcpu *v, const char *fmt, ...); | ||
745 | u64 kvm_gpa_to_mpa(u64 gpa); | ||
746 | extern u64 ia64_call_vsa(u64 proc, u64 arg1, u64 arg2, u64 arg3, | ||
747 | u64 arg4, u64 arg5, u64 arg6, u64 arg7); | ||
748 | |||
749 | extern long vmm_sanity; | ||
750 | |||
751 | #endif | ||
752 | #endif /* __VCPU_H__ */ | ||
diff --git a/arch/ia64/kvm/vmm.c b/arch/ia64/kvm/vmm.c deleted file mode 100644 index 176a12cd56de..000000000000 --- a/arch/ia64/kvm/vmm.c +++ /dev/null | |||
@@ -1,99 +0,0 @@ | |||
1 | /* | ||
2 | * vmm.c: vmm module interface with kvm module | ||
3 | * | ||
4 | * Copyright (c) 2007, Intel Corporation. | ||
5 | * | ||
6 | * Xiantao Zhang (xiantao.zhang@intel.com) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms and conditions of the GNU General Public License, | ||
10 | * version 2, as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along with | ||
18 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | ||
19 | * Place - Suite 330, Boston, MA 02111-1307 USA. | ||
20 | */ | ||
21 | |||
22 | |||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <asm/fpswa.h> | ||
26 | |||
27 | #include "vcpu.h" | ||
28 | |||
29 | MODULE_AUTHOR("Intel"); | ||
30 | MODULE_LICENSE("GPL"); | ||
31 | |||
32 | extern char kvm_ia64_ivt; | ||
33 | extern char kvm_asm_mov_from_ar; | ||
34 | extern char kvm_asm_mov_from_ar_sn2; | ||
35 | extern fpswa_interface_t *vmm_fpswa_interface; | ||
36 | |||
37 | long vmm_sanity = 1; | ||
38 | |||
39 | struct kvm_vmm_info vmm_info = { | ||
40 | .module = THIS_MODULE, | ||
41 | .vmm_entry = vmm_entry, | ||
42 | .tramp_entry = vmm_trampoline, | ||
43 | .vmm_ivt = (unsigned long)&kvm_ia64_ivt, | ||
44 | .patch_mov_ar = (unsigned long)&kvm_asm_mov_from_ar, | ||
45 | .patch_mov_ar_sn2 = (unsigned long)&kvm_asm_mov_from_ar_sn2, | ||
46 | }; | ||
47 | |||
48 | static int __init kvm_vmm_init(void) | ||
49 | { | ||
50 | |||
51 | vmm_fpswa_interface = fpswa_interface; | ||
52 | |||
53 | /*Register vmm data to kvm side*/ | ||
54 | return kvm_init(&vmm_info, 1024, 0, THIS_MODULE); | ||
55 | } | ||
56 | |||
57 | static void __exit kvm_vmm_exit(void) | ||
58 | { | ||
59 | kvm_exit(); | ||
60 | return ; | ||
61 | } | ||
62 | |||
63 | void vmm_spin_lock(vmm_spinlock_t *lock) | ||
64 | { | ||
65 | _vmm_raw_spin_lock(lock); | ||
66 | } | ||
67 | |||
68 | void vmm_spin_unlock(vmm_spinlock_t *lock) | ||
69 | { | ||
70 | _vmm_raw_spin_unlock(lock); | ||
71 | } | ||
72 | |||
73 | static void vcpu_debug_exit(struct kvm_vcpu *vcpu) | ||
74 | { | ||
75 | struct exit_ctl_data *p = &vcpu->arch.exit_data; | ||
76 | long psr; | ||
77 | |||
78 | local_irq_save(psr); | ||
79 | p->exit_reason = EXIT_REASON_DEBUG; | ||
80 | vmm_transition(vcpu); | ||
81 | local_irq_restore(psr); | ||
82 | } | ||
83 | |||
84 | asmlinkage int printk(const char *fmt, ...) | ||
85 | { | ||
86 | struct kvm_vcpu *vcpu = current_vcpu; | ||
87 | va_list args; | ||
88 | int r; | ||
89 | |||
90 | memset(vcpu->arch.log_buf, 0, VMM_LOG_LEN); | ||
91 | va_start(args, fmt); | ||
92 | r = vsnprintf(vcpu->arch.log_buf, VMM_LOG_LEN, fmt, args); | ||
93 | va_end(args); | ||
94 | vcpu_debug_exit(vcpu); | ||
95 | return r; | ||
96 | } | ||
97 | |||
98 | module_init(kvm_vmm_init) | ||
99 | module_exit(kvm_vmm_exit) | ||
diff --git a/arch/ia64/kvm/vmm_ivt.S b/arch/ia64/kvm/vmm_ivt.S deleted file mode 100644 index 397e34a63e18..000000000000 --- a/arch/ia64/kvm/vmm_ivt.S +++ /dev/null | |||
@@ -1,1392 +0,0 @@ | |||
1 | /* | ||
2 | * arch/ia64/kvm/vmm_ivt.S | ||
3 | * | ||
4 | * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co | ||
5 | * Stephane Eranian <eranian@hpl.hp.com> | ||
6 | * David Mosberger <davidm@hpl.hp.com> | ||
7 | * Copyright (C) 2000, 2002-2003 Intel Co | ||
8 | * Asit Mallick <asit.k.mallick@intel.com> | ||
9 | * Suresh Siddha <suresh.b.siddha@intel.com> | ||
10 | * Kenneth Chen <kenneth.w.chen@intel.com> | ||
11 | * Fenghua Yu <fenghua.yu@intel.com> | ||
12 | * | ||
13 | * | ||
14 | * 00/08/23 Asit Mallick <asit.k.mallick@intel.com> TLB handling | ||
15 | * for SMP | ||
16 | * 00/12/20 David Mosberger-Tang <davidm@hpl.hp.com> DTLB/ITLB | ||
17 | * handler now uses virtual PT. | ||
18 | * | ||
19 | * 07/6/20 Xuefei Xu (Anthony Xu) (anthony.xu@intel.com) | ||
20 | * Supporting Intel virtualization architecture | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | /* | ||
25 | * This file defines the interruption vector table used by the CPU. | ||
26 | * It does not include one entry per possible cause of interruption. | ||
27 | * | ||
28 | * The first 20 entries of the table contain 64 bundles each while the | ||
29 | * remaining 48 entries contain only 16 bundles each. | ||
30 | * | ||
31 | * The 64 bundles are used to allow inlining the whole handler for | ||
32 | * critical | ||
33 | * interruptions like TLB misses. | ||
34 | * | ||
35 | * For each entry, the comment is as follows: | ||
36 | * | ||
37 | * // 0x1c00 Entry 7 (size 64 bundles) Data Key Miss | ||
38 | * (12,51) | ||
39 | * entry offset ----/ / / / | ||
40 | * / | ||
41 | * entry number ---------/ / / | ||
42 | * / | ||
43 | * size of the entry -------------/ / | ||
44 | * / | ||
45 | * vector name -------------------------------------/ | ||
46 | * / | ||
47 | * interruptions triggering this vector | ||
48 | * ----------------------/ | ||
49 | * | ||
50 | * The table is 32KB in size and must be aligned on 32KB | ||
51 | * boundary. | ||
52 | * (The CPU ignores the 15 lower bits of the address) | ||
53 | * | ||
54 | * Table is based upon EAS2.6 (Oct 1999) | ||
55 | */ | ||
56 | |||
57 | |||
58 | #include <asm/asmmacro.h> | ||
59 | #include <asm/cache.h> | ||
60 | #include <asm/pgtable.h> | ||
61 | |||
62 | #include "asm-offsets.h" | ||
63 | #include "vcpu.h" | ||
64 | #include "kvm_minstate.h" | ||
65 | #include "vti.h" | ||
66 | |||
67 | #if 0 | ||
68 | # define PSR_DEFAULT_BITS psr.ac | ||
69 | #else | ||
70 | # define PSR_DEFAULT_BITS 0 | ||
71 | #endif | ||
72 | |||
73 | #define KVM_FAULT(n) \ | ||
74 | kvm_fault_##n:; \ | ||
75 | mov r19=n;; \ | ||
76 | br.sptk.many kvm_vmm_panic; \ | ||
77 | ;; \ | ||
78 | |||
79 | #define KVM_REFLECT(n) \ | ||
80 | mov r31=pr; \ | ||
81 | mov r19=n; /* prepare to save predicates */ \ | ||
82 | mov r29=cr.ipsr; \ | ||
83 | ;; \ | ||
84 | tbit.z p6,p7=r29,IA64_PSR_VM_BIT; \ | ||
85 | (p7) br.sptk.many kvm_dispatch_reflection; \ | ||
86 | br.sptk.many kvm_vmm_panic; \ | ||
87 | |||
88 | GLOBAL_ENTRY(kvm_vmm_panic) | ||
89 | KVM_SAVE_MIN_WITH_COVER_R19 | ||
90 | alloc r14=ar.pfs,0,0,1,0 | ||
91 | mov out0=r15 | ||
92 | adds r3=8,r2 // set up second base pointer | ||
93 | ;; | ||
94 | ssm psr.ic | ||
95 | ;; | ||
96 | srlz.i // guarantee that interruption collection is on | ||
97 | ;; | ||
98 | (p15) ssm psr.i // restore psr. | ||
99 | addl r14=@gprel(ia64_leave_hypervisor),gp | ||
100 | ;; | ||
101 | KVM_SAVE_REST | ||
102 | mov rp=r14 | ||
103 | ;; | ||
104 | br.call.sptk.many b6=vmm_panic_handler; | ||
105 | END(kvm_vmm_panic) | ||
106 | |||
107 | .section .text..ivt,"ax" | ||
108 | |||
109 | .align 32768 // align on 32KB boundary | ||
110 | .global kvm_ia64_ivt | ||
111 | kvm_ia64_ivt: | ||
112 | /////////////////////////////////////////////////////////////// | ||
113 | // 0x0000 Entry 0 (size 64 bundles) VHPT Translation (8,20,47) | ||
114 | ENTRY(kvm_vhpt_miss) | ||
115 | KVM_FAULT(0) | ||
116 | END(kvm_vhpt_miss) | ||
117 | |||
118 | .org kvm_ia64_ivt+0x400 | ||
119 | //////////////////////////////////////////////////////////////// | ||
120 | // 0x0400 Entry 1 (size 64 bundles) ITLB (21) | ||
121 | ENTRY(kvm_itlb_miss) | ||
122 | mov r31 = pr | ||
123 | mov r29=cr.ipsr; | ||
124 | ;; | ||
125 | tbit.z p6,p7=r29,IA64_PSR_VM_BIT; | ||
126 | (p6) br.sptk kvm_alt_itlb_miss | ||
127 | mov r19 = 1 | ||
128 | br.sptk kvm_itlb_miss_dispatch | ||
129 | KVM_FAULT(1); | ||
130 | END(kvm_itlb_miss) | ||
131 | |||
132 | .org kvm_ia64_ivt+0x0800 | ||
133 | ////////////////////////////////////////////////////////////////// | ||
134 | // 0x0800 Entry 2 (size 64 bundles) DTLB (9,48) | ||
135 | ENTRY(kvm_dtlb_miss) | ||
136 | mov r31 = pr | ||
137 | mov r29=cr.ipsr; | ||
138 | ;; | ||
139 | tbit.z p6,p7=r29,IA64_PSR_VM_BIT; | ||
140 | (p6) br.sptk kvm_alt_dtlb_miss | ||
141 | br.sptk kvm_dtlb_miss_dispatch | ||
142 | END(kvm_dtlb_miss) | ||
143 | |||
144 | .org kvm_ia64_ivt+0x0c00 | ||
145 | //////////////////////////////////////////////////////////////////// | ||
146 | // 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19) | ||
147 | ENTRY(kvm_alt_itlb_miss) | ||
148 | mov r16=cr.ifa // get address that caused the TLB miss | ||
149 | ;; | ||
150 | movl r17=PAGE_KERNEL | ||
151 | mov r24=cr.ipsr | ||
152 | movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff) | ||
153 | ;; | ||
154 | and r19=r19,r16 // clear ed, reserved bits, and PTE control bits | ||
155 | ;; | ||
156 | or r19=r17,r19 // insert PTE control bits into r19 | ||
157 | ;; | ||
158 | movl r20=IA64_GRANULE_SHIFT<<2 | ||
159 | ;; | ||
160 | mov cr.itir=r20 | ||
161 | ;; | ||
162 | itc.i r19 // insert the TLB entry | ||
163 | mov pr=r31,-1 | ||
164 | rfi | ||
165 | END(kvm_alt_itlb_miss) | ||
166 | |||
167 | .org kvm_ia64_ivt+0x1000 | ||
168 | ///////////////////////////////////////////////////////////////////// | ||
169 | // 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46) | ||
170 | ENTRY(kvm_alt_dtlb_miss) | ||
171 | mov r16=cr.ifa // get address that caused the TLB miss | ||
172 | ;; | ||
173 | movl r17=PAGE_KERNEL | ||
174 | movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff) | ||
175 | mov r24=cr.ipsr | ||
176 | ;; | ||
177 | and r19=r19,r16 // clear ed, reserved bits, and PTE control bits | ||
178 | ;; | ||
179 | or r19=r19,r17 // insert PTE control bits into r19 | ||
180 | ;; | ||
181 | movl r20=IA64_GRANULE_SHIFT<<2 | ||
182 | ;; | ||
183 | mov cr.itir=r20 | ||
184 | ;; | ||
185 | itc.d r19 // insert the TLB entry | ||
186 | mov pr=r31,-1 | ||
187 | rfi | ||
188 | END(kvm_alt_dtlb_miss) | ||
189 | |||
190 | .org kvm_ia64_ivt+0x1400 | ||
191 | ////////////////////////////////////////////////////////////////////// | ||
192 | // 0x1400 Entry 5 (size 64 bundles) Data nested TLB (6,45) | ||
193 | ENTRY(kvm_nested_dtlb_miss) | ||
194 | KVM_FAULT(5) | ||
195 | END(kvm_nested_dtlb_miss) | ||
196 | |||
197 | .org kvm_ia64_ivt+0x1800 | ||
198 | ///////////////////////////////////////////////////////////////////// | ||
199 | // 0x1800 Entry 6 (size 64 bundles) Instruction Key Miss (24) | ||
200 | ENTRY(kvm_ikey_miss) | ||
201 | KVM_REFLECT(6) | ||
202 | END(kvm_ikey_miss) | ||
203 | |||
204 | .org kvm_ia64_ivt+0x1c00 | ||
205 | ///////////////////////////////////////////////////////////////////// | ||
206 | // 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51) | ||
207 | ENTRY(kvm_dkey_miss) | ||
208 | KVM_REFLECT(7) | ||
209 | END(kvm_dkey_miss) | ||
210 | |||
211 | .org kvm_ia64_ivt+0x2000 | ||
212 | //////////////////////////////////////////////////////////////////// | ||
213 | // 0x2000 Entry 8 (size 64 bundles) Dirty-bit (54) | ||
214 | ENTRY(kvm_dirty_bit) | ||
215 | KVM_REFLECT(8) | ||
216 | END(kvm_dirty_bit) | ||
217 | |||
218 | .org kvm_ia64_ivt+0x2400 | ||
219 | //////////////////////////////////////////////////////////////////// | ||
220 | // 0x2400 Entry 9 (size 64 bundles) Instruction Access-bit (27) | ||
221 | ENTRY(kvm_iaccess_bit) | ||
222 | KVM_REFLECT(9) | ||
223 | END(kvm_iaccess_bit) | ||
224 | |||
225 | .org kvm_ia64_ivt+0x2800 | ||
226 | /////////////////////////////////////////////////////////////////// | ||
227 | // 0x2800 Entry 10 (size 64 bundles) Data Access-bit (15,55) | ||
228 | ENTRY(kvm_daccess_bit) | ||
229 | KVM_REFLECT(10) | ||
230 | END(kvm_daccess_bit) | ||
231 | |||
232 | .org kvm_ia64_ivt+0x2c00 | ||
233 | ///////////////////////////////////////////////////////////////// | ||
234 | // 0x2c00 Entry 11 (size 64 bundles) Break instruction (33) | ||
235 | ENTRY(kvm_break_fault) | ||
236 | mov r31=pr | ||
237 | mov r19=11 | ||
238 | mov r29=cr.ipsr | ||
239 | ;; | ||
240 | KVM_SAVE_MIN_WITH_COVER_R19 | ||
241 | ;; | ||
242 | alloc r14=ar.pfs,0,0,4,0 //(must be first in insn group!) | ||
243 | mov out0=cr.ifa | ||
244 | mov out2=cr.isr // FIXME: pity to make this slow access twice | ||
245 | mov out3=cr.iim // FIXME: pity to make this slow access twice | ||
246 | adds r3=8,r2 // set up second base pointer | ||
247 | ;; | ||
248 | ssm psr.ic | ||
249 | ;; | ||
250 | srlz.i // guarantee that interruption collection is on | ||
251 | ;; | ||
252 | (p15)ssm psr.i // restore psr.i | ||
253 | addl r14=@gprel(ia64_leave_hypervisor),gp | ||
254 | ;; | ||
255 | KVM_SAVE_REST | ||
256 | mov rp=r14 | ||
257 | ;; | ||
258 | adds out1=16,sp | ||
259 | br.call.sptk.many b6=kvm_ia64_handle_break | ||
260 | ;; | ||
261 | END(kvm_break_fault) | ||
262 | |||
263 | .org kvm_ia64_ivt+0x3000 | ||
264 | ///////////////////////////////////////////////////////////////// | ||
265 | // 0x3000 Entry 12 (size 64 bundles) External Interrupt (4) | ||
266 | ENTRY(kvm_interrupt) | ||
267 | mov r31=pr // prepare to save predicates | ||
268 | mov r19=12 | ||
269 | mov r29=cr.ipsr | ||
270 | ;; | ||
271 | tbit.z p6,p7=r29,IA64_PSR_VM_BIT | ||
272 | tbit.z p0,p15=r29,IA64_PSR_I_BIT | ||
273 | ;; | ||
274 | (p7) br.sptk kvm_dispatch_interrupt | ||
275 | ;; | ||
276 | mov r27=ar.rsc /* M */ | ||
277 | mov r20=r1 /* A */ | ||
278 | mov r25=ar.unat /* M */ | ||
279 | mov r26=ar.pfs /* I */ | ||
280 | mov r28=cr.iip /* M */ | ||
281 | cover /* B (or nothing) */ | ||
282 | ;; | ||
283 | mov r1=sp | ||
284 | ;; | ||
285 | invala /* M */ | ||
286 | mov r30=cr.ifs | ||
287 | ;; | ||
288 | addl r1=-VMM_PT_REGS_SIZE,r1 | ||
289 | ;; | ||
290 | adds r17=2*L1_CACHE_BYTES,r1 /* really: biggest cache-line size */ | ||
291 | adds r16=PT(CR_IPSR),r1 | ||
292 | ;; | ||
293 | lfetch.fault.excl.nt1 [r17],L1_CACHE_BYTES | ||
294 | st8 [r16]=r29 /* save cr.ipsr */ | ||
295 | ;; | ||
296 | lfetch.fault.excl.nt1 [r17] | ||
297 | mov r29=b0 | ||
298 | ;; | ||
299 | adds r16=PT(R8),r1 /* initialize first base pointer */ | ||
300 | adds r17=PT(R9),r1 /* initialize second base pointer */ | ||
301 | mov r18=r0 /* make sure r18 isn't NaT */ | ||
302 | ;; | ||
303 | .mem.offset 0,0; st8.spill [r16]=r8,16 | ||
304 | .mem.offset 8,0; st8.spill [r17]=r9,16 | ||
305 | ;; | ||
306 | .mem.offset 0,0; st8.spill [r16]=r10,24 | ||
307 | .mem.offset 8,0; st8.spill [r17]=r11,24 | ||
308 | ;; | ||
309 | st8 [r16]=r28,16 /* save cr.iip */ | ||
310 | st8 [r17]=r30,16 /* save cr.ifs */ | ||
311 | mov r8=ar.fpsr /* M */ | ||
312 | mov r9=ar.csd | ||
313 | mov r10=ar.ssd | ||
314 | movl r11=FPSR_DEFAULT /* L-unit */ | ||
315 | ;; | ||
316 | st8 [r16]=r25,16 /* save ar.unat */ | ||
317 | st8 [r17]=r26,16 /* save ar.pfs */ | ||
318 | shl r18=r18,16 /* compute ar.rsc to be used for "loadrs" */ | ||
319 | ;; | ||
320 | st8 [r16]=r27,16 /* save ar.rsc */ | ||
321 | adds r17=16,r17 /* skip over ar_rnat field */ | ||
322 | ;; | ||
323 | st8 [r17]=r31,16 /* save predicates */ | ||
324 | adds r16=16,r16 /* skip over ar_bspstore field */ | ||
325 | ;; | ||
326 | st8 [r16]=r29,16 /* save b0 */ | ||
327 | st8 [r17]=r18,16 /* save ar.rsc value for "loadrs" */ | ||
328 | ;; | ||
329 | .mem.offset 0,0; st8.spill [r16]=r20,16 /* save original r1 */ | ||
330 | .mem.offset 8,0; st8.spill [r17]=r12,16 | ||
331 | adds r12=-16,r1 | ||
332 | /* switch to kernel memory stack (with 16 bytes of scratch) */ | ||
333 | ;; | ||
334 | .mem.offset 0,0; st8.spill [r16]=r13,16 | ||
335 | .mem.offset 8,0; st8.spill [r17]=r8,16 /* save ar.fpsr */ | ||
336 | ;; | ||
337 | .mem.offset 0,0; st8.spill [r16]=r15,16 | ||
338 | .mem.offset 8,0; st8.spill [r17]=r14,16 | ||
339 | dep r14=-1,r0,60,4 | ||
340 | ;; | ||
341 | .mem.offset 0,0; st8.spill [r16]=r2,16 | ||
342 | .mem.offset 8,0; st8.spill [r17]=r3,16 | ||
343 | adds r2=VMM_PT_REGS_R16_OFFSET,r1 | ||
344 | adds r14 = VMM_VCPU_GP_OFFSET,r13 | ||
345 | ;; | ||
346 | mov r8=ar.ccv | ||
347 | ld8 r14 = [r14] | ||
348 | ;; | ||
349 | mov r1=r14 /* establish kernel global pointer */ | ||
350 | ;; \ | ||
351 | bsw.1 | ||
352 | ;; | ||
353 | alloc r14=ar.pfs,0,0,1,0 // must be first in an insn group | ||
354 | mov out0=r13 | ||
355 | ;; | ||
356 | ssm psr.ic | ||
357 | ;; | ||
358 | srlz.i | ||
359 | ;; | ||
360 | //(p15) ssm psr.i | ||
361 | adds r3=8,r2 // set up second base pointer for SAVE_REST | ||
362 | srlz.i // ensure everybody knows psr.ic is back on | ||
363 | ;; | ||
364 | .mem.offset 0,0; st8.spill [r2]=r16,16 | ||
365 | .mem.offset 8,0; st8.spill [r3]=r17,16 | ||
366 | ;; | ||
367 | .mem.offset 0,0; st8.spill [r2]=r18,16 | ||
368 | .mem.offset 8,0; st8.spill [r3]=r19,16 | ||
369 | ;; | ||
370 | .mem.offset 0,0; st8.spill [r2]=r20,16 | ||
371 | .mem.offset 8,0; st8.spill [r3]=r21,16 | ||
372 | mov r18=b6 | ||
373 | ;; | ||
374 | .mem.offset 0,0; st8.spill [r2]=r22,16 | ||
375 | .mem.offset 8,0; st8.spill [r3]=r23,16 | ||
376 | mov r19=b7 | ||
377 | ;; | ||
378 | .mem.offset 0,0; st8.spill [r2]=r24,16 | ||
379 | .mem.offset 8,0; st8.spill [r3]=r25,16 | ||
380 | ;; | ||
381 | .mem.offset 0,0; st8.spill [r2]=r26,16 | ||
382 | .mem.offset 8,0; st8.spill [r3]=r27,16 | ||
383 | ;; | ||
384 | .mem.offset 0,0; st8.spill [r2]=r28,16 | ||
385 | .mem.offset 8,0; st8.spill [r3]=r29,16 | ||
386 | ;; | ||
387 | .mem.offset 0,0; st8.spill [r2]=r30,16 | ||
388 | .mem.offset 8,0; st8.spill [r3]=r31,32 | ||
389 | ;; | ||
390 | mov ar.fpsr=r11 /* M-unit */ | ||
391 | st8 [r2]=r8,8 /* ar.ccv */ | ||
392 | adds r24=PT(B6)-PT(F7),r3 | ||
393 | ;; | ||
394 | stf.spill [r2]=f6,32 | ||
395 | stf.spill [r3]=f7,32 | ||
396 | ;; | ||
397 | stf.spill [r2]=f8,32 | ||
398 | stf.spill [r3]=f9,32 | ||
399 | ;; | ||
400 | stf.spill [r2]=f10 | ||
401 | stf.spill [r3]=f11 | ||
402 | adds r25=PT(B7)-PT(F11),r3 | ||
403 | ;; | ||
404 | st8 [r24]=r18,16 /* b6 */ | ||
405 | st8 [r25]=r19,16 /* b7 */ | ||
406 | ;; | ||
407 | st8 [r24]=r9 /* ar.csd */ | ||
408 | st8 [r25]=r10 /* ar.ssd */ | ||
409 | ;; | ||
410 | srlz.d // make sure we see the effect of cr.ivr | ||
411 | addl r14=@gprel(ia64_leave_nested),gp | ||
412 | ;; | ||
413 | mov rp=r14 | ||
414 | br.call.sptk.many b6=kvm_ia64_handle_irq | ||
415 | ;; | ||
416 | END(kvm_interrupt) | ||
417 | |||
418 | .global kvm_dispatch_vexirq | ||
419 | .org kvm_ia64_ivt+0x3400 | ||
420 | ////////////////////////////////////////////////////////////////////// | ||
421 | // 0x3400 Entry 13 (size 64 bundles) Reserved | ||
422 | ENTRY(kvm_virtual_exirq) | ||
423 | mov r31=pr | ||
424 | mov r19=13 | ||
425 | mov r30 =r0 | ||
426 | ;; | ||
427 | kvm_dispatch_vexirq: | ||
428 | cmp.eq p6,p0 = 1,r30 | ||
429 | ;; | ||
430 | (p6) add r29 = VMM_VCPU_SAVED_GP_OFFSET,r21 | ||
431 | ;; | ||
432 | (p6) ld8 r1 = [r29] | ||
433 | ;; | ||
434 | KVM_SAVE_MIN_WITH_COVER_R19 | ||
435 | alloc r14=ar.pfs,0,0,1,0 | ||
436 | mov out0=r13 | ||
437 | |||
438 | ssm psr.ic | ||
439 | ;; | ||
440 | srlz.i // guarantee that interruption collection is on | ||
441 | ;; | ||
442 | (p15) ssm psr.i // restore psr.i | ||
443 | adds r3=8,r2 // set up second base pointer | ||
444 | ;; | ||
445 | KVM_SAVE_REST | ||
446 | addl r14=@gprel(ia64_leave_hypervisor),gp | ||
447 | ;; | ||
448 | mov rp=r14 | ||
449 | br.call.sptk.many b6=kvm_vexirq | ||
450 | END(kvm_virtual_exirq) | ||
451 | |||
452 | .org kvm_ia64_ivt+0x3800 | ||
453 | ///////////////////////////////////////////////////////////////////// | ||
454 | // 0x3800 Entry 14 (size 64 bundles) Reserved | ||
455 | KVM_FAULT(14) | ||
456 | // this code segment is from 2.6.16.13 | ||
457 | |||
458 | .org kvm_ia64_ivt+0x3c00 | ||
459 | /////////////////////////////////////////////////////////////////////// | ||
460 | // 0x3c00 Entry 15 (size 64 bundles) Reserved | ||
461 | KVM_FAULT(15) | ||
462 | |||
463 | .org kvm_ia64_ivt+0x4000 | ||
464 | /////////////////////////////////////////////////////////////////////// | ||
465 | // 0x4000 Entry 16 (size 64 bundles) Reserved | ||
466 | KVM_FAULT(16) | ||
467 | |||
468 | .org kvm_ia64_ivt+0x4400 | ||
469 | ////////////////////////////////////////////////////////////////////// | ||
470 | // 0x4400 Entry 17 (size 64 bundles) Reserved | ||
471 | KVM_FAULT(17) | ||
472 | |||
473 | .org kvm_ia64_ivt+0x4800 | ||
474 | ////////////////////////////////////////////////////////////////////// | ||
475 | // 0x4800 Entry 18 (size 64 bundles) Reserved | ||
476 | KVM_FAULT(18) | ||
477 | |||
478 | .org kvm_ia64_ivt+0x4c00 | ||
479 | ////////////////////////////////////////////////////////////////////// | ||
480 | // 0x4c00 Entry 19 (size 64 bundles) Reserved | ||
481 | KVM_FAULT(19) | ||
482 | |||
483 | .org kvm_ia64_ivt+0x5000 | ||
484 | ////////////////////////////////////////////////////////////////////// | ||
485 | // 0x5000 Entry 20 (size 16 bundles) Page Not Present | ||
486 | ENTRY(kvm_page_not_present) | ||
487 | KVM_REFLECT(20) | ||
488 | END(kvm_page_not_present) | ||
489 | |||
490 | .org kvm_ia64_ivt+0x5100 | ||
491 | /////////////////////////////////////////////////////////////////////// | ||
492 | // 0x5100 Entry 21 (size 16 bundles) Key Permission vector | ||
493 | ENTRY(kvm_key_permission) | ||
494 | KVM_REFLECT(21) | ||
495 | END(kvm_key_permission) | ||
496 | |||
497 | .org kvm_ia64_ivt+0x5200 | ||
498 | ////////////////////////////////////////////////////////////////////// | ||
499 | // 0x5200 Entry 22 (size 16 bundles) Instruction Access Rights (26) | ||
500 | ENTRY(kvm_iaccess_rights) | ||
501 | KVM_REFLECT(22) | ||
502 | END(kvm_iaccess_rights) | ||
503 | |||
504 | .org kvm_ia64_ivt+0x5300 | ||
505 | ////////////////////////////////////////////////////////////////////// | ||
506 | // 0x5300 Entry 23 (size 16 bundles) Data Access Rights (14,53) | ||
507 | ENTRY(kvm_daccess_rights) | ||
508 | KVM_REFLECT(23) | ||
509 | END(kvm_daccess_rights) | ||
510 | |||
511 | .org kvm_ia64_ivt+0x5400 | ||
512 | ///////////////////////////////////////////////////////////////////// | ||
513 | // 0x5400 Entry 24 (size 16 bundles) General Exception (5,32,34,36,38,39) | ||
514 | ENTRY(kvm_general_exception) | ||
515 | KVM_REFLECT(24) | ||
516 | KVM_FAULT(24) | ||
517 | END(kvm_general_exception) | ||
518 | |||
519 | .org kvm_ia64_ivt+0x5500 | ||
520 | ////////////////////////////////////////////////////////////////////// | ||
521 | // 0x5500 Entry 25 (size 16 bundles) Disabled FP-Register (35) | ||
522 | ENTRY(kvm_disabled_fp_reg) | ||
523 | KVM_REFLECT(25) | ||
524 | END(kvm_disabled_fp_reg) | ||
525 | |||
526 | .org kvm_ia64_ivt+0x5600 | ||
527 | //////////////////////////////////////////////////////////////////// | ||
528 | // 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50) | ||
529 | ENTRY(kvm_nat_consumption) | ||
530 | KVM_REFLECT(26) | ||
531 | END(kvm_nat_consumption) | ||
532 | |||
533 | .org kvm_ia64_ivt+0x5700 | ||
534 | ///////////////////////////////////////////////////////////////////// | ||
535 | // 0x5700 Entry 27 (size 16 bundles) Speculation (40) | ||
536 | ENTRY(kvm_speculation_vector) | ||
537 | KVM_REFLECT(27) | ||
538 | END(kvm_speculation_vector) | ||
539 | |||
540 | .org kvm_ia64_ivt+0x5800 | ||
541 | ///////////////////////////////////////////////////////////////////// | ||
542 | // 0x5800 Entry 28 (size 16 bundles) Reserved | ||
543 | KVM_FAULT(28) | ||
544 | |||
545 | .org kvm_ia64_ivt+0x5900 | ||
546 | /////////////////////////////////////////////////////////////////// | ||
547 | // 0x5900 Entry 29 (size 16 bundles) Debug (16,28,56) | ||
548 | ENTRY(kvm_debug_vector) | ||
549 | KVM_FAULT(29) | ||
550 | END(kvm_debug_vector) | ||
551 | |||
552 | .org kvm_ia64_ivt+0x5a00 | ||
553 | /////////////////////////////////////////////////////////////// | ||
554 | // 0x5a00 Entry 30 (size 16 bundles) Unaligned Reference (57) | ||
555 | ENTRY(kvm_unaligned_access) | ||
556 | KVM_REFLECT(30) | ||
557 | END(kvm_unaligned_access) | ||
558 | |||
559 | .org kvm_ia64_ivt+0x5b00 | ||
560 | ////////////////////////////////////////////////////////////////////// | ||
561 | // 0x5b00 Entry 31 (size 16 bundles) Unsupported Data Reference (57) | ||
562 | ENTRY(kvm_unsupported_data_reference) | ||
563 | KVM_REFLECT(31) | ||
564 | END(kvm_unsupported_data_reference) | ||
565 | |||
566 | .org kvm_ia64_ivt+0x5c00 | ||
567 | //////////////////////////////////////////////////////////////////// | ||
568 | // 0x5c00 Entry 32 (size 16 bundles) Floating Point FAULT (65) | ||
569 | ENTRY(kvm_floating_point_fault) | ||
570 | KVM_REFLECT(32) | ||
571 | END(kvm_floating_point_fault) | ||
572 | |||
573 | .org kvm_ia64_ivt+0x5d00 | ||
574 | ///////////////////////////////////////////////////////////////////// | ||
575 | // 0x5d00 Entry 33 (size 16 bundles) Floating Point Trap (66) | ||
576 | ENTRY(kvm_floating_point_trap) | ||
577 | KVM_REFLECT(33) | ||
578 | END(kvm_floating_point_trap) | ||
579 | |||
580 | .org kvm_ia64_ivt+0x5e00 | ||
581 | ////////////////////////////////////////////////////////////////////// | ||
582 | // 0x5e00 Entry 34 (size 16 bundles) Lower Privilege Transfer Trap (66) | ||
583 | ENTRY(kvm_lower_privilege_trap) | ||
584 | KVM_REFLECT(34) | ||
585 | END(kvm_lower_privilege_trap) | ||
586 | |||
587 | .org kvm_ia64_ivt+0x5f00 | ||
588 | ////////////////////////////////////////////////////////////////////// | ||
589 | // 0x5f00 Entry 35 (size 16 bundles) Taken Branch Trap (68) | ||
590 | ENTRY(kvm_taken_branch_trap) | ||
591 | KVM_REFLECT(35) | ||
592 | END(kvm_taken_branch_trap) | ||
593 | |||
594 | .org kvm_ia64_ivt+0x6000 | ||
595 | //////////////////////////////////////////////////////////////////// | ||
596 | // 0x6000 Entry 36 (size 16 bundles) Single Step Trap (69) | ||
597 | ENTRY(kvm_single_step_trap) | ||
598 | KVM_REFLECT(36) | ||
599 | END(kvm_single_step_trap) | ||
600 | .global kvm_virtualization_fault_back | ||
601 | .org kvm_ia64_ivt+0x6100 | ||
602 | ///////////////////////////////////////////////////////////////////// | ||
603 | // 0x6100 Entry 37 (size 16 bundles) Virtualization Fault | ||
604 | ENTRY(kvm_virtualization_fault) | ||
605 | mov r31=pr | ||
606 | adds r16 = VMM_VCPU_SAVED_GP_OFFSET,r21 | ||
607 | ;; | ||
608 | st8 [r16] = r1 | ||
609 | adds r17 = VMM_VCPU_GP_OFFSET, r21 | ||
610 | ;; | ||
611 | ld8 r1 = [r17] | ||
612 | cmp.eq p6,p0=EVENT_MOV_FROM_AR,r24 | ||
613 | cmp.eq p7,p0=EVENT_MOV_FROM_RR,r24 | ||
614 | cmp.eq p8,p0=EVENT_MOV_TO_RR,r24 | ||
615 | cmp.eq p9,p0=EVENT_RSM,r24 | ||
616 | cmp.eq p10,p0=EVENT_SSM,r24 | ||
617 | cmp.eq p11,p0=EVENT_MOV_TO_PSR,r24 | ||
618 | cmp.eq p12,p0=EVENT_THASH,r24 | ||
619 | (p6) br.dptk.many kvm_asm_mov_from_ar | ||
620 | (p7) br.dptk.many kvm_asm_mov_from_rr | ||
621 | (p8) br.dptk.many kvm_asm_mov_to_rr | ||
622 | (p9) br.dptk.many kvm_asm_rsm | ||
623 | (p10) br.dptk.many kvm_asm_ssm | ||
624 | (p11) br.dptk.many kvm_asm_mov_to_psr | ||
625 | (p12) br.dptk.many kvm_asm_thash | ||
626 | ;; | ||
627 | kvm_virtualization_fault_back: | ||
628 | adds r16 = VMM_VCPU_SAVED_GP_OFFSET,r21 | ||
629 | ;; | ||
630 | ld8 r1 = [r16] | ||
631 | ;; | ||
632 | mov r19=37 | ||
633 | adds r16 = VMM_VCPU_CAUSE_OFFSET,r21 | ||
634 | adds r17 = VMM_VCPU_OPCODE_OFFSET,r21 | ||
635 | ;; | ||
636 | st8 [r16] = r24 | ||
637 | st8 [r17] = r25 | ||
638 | ;; | ||
639 | cmp.ne p6,p0=EVENT_RFI, r24 | ||
640 | (p6) br.sptk kvm_dispatch_virtualization_fault | ||
641 | ;; | ||
642 | adds r18=VMM_VPD_BASE_OFFSET,r21 | ||
643 | ;; | ||
644 | ld8 r18=[r18] | ||
645 | ;; | ||
646 | adds r18=VMM_VPD_VIFS_OFFSET,r18 | ||
647 | ;; | ||
648 | ld8 r18=[r18] | ||
649 | ;; | ||
650 | tbit.z p6,p0=r18,63 | ||
651 | (p6) br.sptk kvm_dispatch_virtualization_fault | ||
652 | ;; | ||
653 | //if vifs.v=1 desert current register frame | ||
654 | alloc r18=ar.pfs,0,0,0,0 | ||
655 | br.sptk kvm_dispatch_virtualization_fault | ||
656 | END(kvm_virtualization_fault) | ||
657 | |||
658 | .org kvm_ia64_ivt+0x6200 | ||
659 | ////////////////////////////////////////////////////////////// | ||
660 | // 0x6200 Entry 38 (size 16 bundles) Reserved | ||
661 | KVM_FAULT(38) | ||
662 | |||
663 | .org kvm_ia64_ivt+0x6300 | ||
664 | ///////////////////////////////////////////////////////////////// | ||
665 | // 0x6300 Entry 39 (size 16 bundles) Reserved | ||
666 | KVM_FAULT(39) | ||
667 | |||
668 | .org kvm_ia64_ivt+0x6400 | ||
669 | ///////////////////////////////////////////////////////////////// | ||
670 | // 0x6400 Entry 40 (size 16 bundles) Reserved | ||
671 | KVM_FAULT(40) | ||
672 | |||
673 | .org kvm_ia64_ivt+0x6500 | ||
674 | ////////////////////////////////////////////////////////////////// | ||
675 | // 0x6500 Entry 41 (size 16 bundles) Reserved | ||
676 | KVM_FAULT(41) | ||
677 | |||
678 | .org kvm_ia64_ivt+0x6600 | ||
679 | ////////////////////////////////////////////////////////////////// | ||
680 | // 0x6600 Entry 42 (size 16 bundles) Reserved | ||
681 | KVM_FAULT(42) | ||
682 | |||
683 | .org kvm_ia64_ivt+0x6700 | ||
684 | ////////////////////////////////////////////////////////////////// | ||
685 | // 0x6700 Entry 43 (size 16 bundles) Reserved | ||
686 | KVM_FAULT(43) | ||
687 | |||
688 | .org kvm_ia64_ivt+0x6800 | ||
689 | ////////////////////////////////////////////////////////////////// | ||
690 | // 0x6800 Entry 44 (size 16 bundles) Reserved | ||
691 | KVM_FAULT(44) | ||
692 | |||
693 | .org kvm_ia64_ivt+0x6900 | ||
694 | /////////////////////////////////////////////////////////////////// | ||
695 | // 0x6900 Entry 45 (size 16 bundles) IA-32 Exeception | ||
696 | //(17,18,29,41,42,43,44,58,60,61,62,72,73,75,76,77) | ||
697 | ENTRY(kvm_ia32_exception) | ||
698 | KVM_FAULT(45) | ||
699 | END(kvm_ia32_exception) | ||
700 | |||
701 | .org kvm_ia64_ivt+0x6a00 | ||
702 | //////////////////////////////////////////////////////////////////// | ||
703 | // 0x6a00 Entry 46 (size 16 bundles) IA-32 Intercept (30,31,59,70,71) | ||
704 | ENTRY(kvm_ia32_intercept) | ||
705 | KVM_FAULT(47) | ||
706 | END(kvm_ia32_intercept) | ||
707 | |||
708 | .org kvm_ia64_ivt+0x6c00 | ||
709 | ///////////////////////////////////////////////////////////////////// | ||
710 | // 0x6c00 Entry 48 (size 16 bundles) Reserved | ||
711 | KVM_FAULT(48) | ||
712 | |||
713 | .org kvm_ia64_ivt+0x6d00 | ||
714 | ////////////////////////////////////////////////////////////////////// | ||
715 | // 0x6d00 Entry 49 (size 16 bundles) Reserved | ||
716 | KVM_FAULT(49) | ||
717 | |||
718 | .org kvm_ia64_ivt+0x6e00 | ||
719 | ////////////////////////////////////////////////////////////////////// | ||
720 | // 0x6e00 Entry 50 (size 16 bundles) Reserved | ||
721 | KVM_FAULT(50) | ||
722 | |||
723 | .org kvm_ia64_ivt+0x6f00 | ||
724 | ///////////////////////////////////////////////////////////////////// | ||
725 | // 0x6f00 Entry 51 (size 16 bundles) Reserved | ||
726 | KVM_FAULT(52) | ||
727 | |||
728 | .org kvm_ia64_ivt+0x7100 | ||
729 | //////////////////////////////////////////////////////////////////// | ||
730 | // 0x7100 Entry 53 (size 16 bundles) Reserved | ||
731 | KVM_FAULT(53) | ||
732 | |||
733 | .org kvm_ia64_ivt+0x7200 | ||
734 | ///////////////////////////////////////////////////////////////////// | ||
735 | // 0x7200 Entry 54 (size 16 bundles) Reserved | ||
736 | KVM_FAULT(54) | ||
737 | |||
738 | .org kvm_ia64_ivt+0x7300 | ||
739 | //////////////////////////////////////////////////////////////////// | ||
740 | // 0x7300 Entry 55 (size 16 bundles) Reserved | ||
741 | KVM_FAULT(55) | ||
742 | |||
743 | .org kvm_ia64_ivt+0x7400 | ||
744 | //////////////////////////////////////////////////////////////////// | ||
745 | // 0x7400 Entry 56 (size 16 bundles) Reserved | ||
746 | KVM_FAULT(56) | ||
747 | |||
748 | .org kvm_ia64_ivt+0x7500 | ||
749 | ///////////////////////////////////////////////////////////////////// | ||
750 | // 0x7500 Entry 57 (size 16 bundles) Reserved | ||
751 | KVM_FAULT(57) | ||
752 | |||
753 | .org kvm_ia64_ivt+0x7600 | ||
754 | ///////////////////////////////////////////////////////////////////// | ||
755 | // 0x7600 Entry 58 (size 16 bundles) Reserved | ||
756 | KVM_FAULT(58) | ||
757 | |||
758 | .org kvm_ia64_ivt+0x7700 | ||
759 | //////////////////////////////////////////////////////////////////// | ||
760 | // 0x7700 Entry 59 (size 16 bundles) Reserved | ||
761 | KVM_FAULT(59) | ||
762 | |||
763 | .org kvm_ia64_ivt+0x7800 | ||
764 | //////////////////////////////////////////////////////////////////// | ||
765 | // 0x7800 Entry 60 (size 16 bundles) Reserved | ||
766 | KVM_FAULT(60) | ||
767 | |||
768 | .org kvm_ia64_ivt+0x7900 | ||
769 | ///////////////////////////////////////////////////////////////////// | ||
770 | // 0x7900 Entry 61 (size 16 bundles) Reserved | ||
771 | KVM_FAULT(61) | ||
772 | |||
773 | .org kvm_ia64_ivt+0x7a00 | ||
774 | ///////////////////////////////////////////////////////////////////// | ||
775 | // 0x7a00 Entry 62 (size 16 bundles) Reserved | ||
776 | KVM_FAULT(62) | ||
777 | |||
778 | .org kvm_ia64_ivt+0x7b00 | ||
779 | ///////////////////////////////////////////////////////////////////// | ||
780 | // 0x7b00 Entry 63 (size 16 bundles) Reserved | ||
781 | KVM_FAULT(63) | ||
782 | |||
783 | .org kvm_ia64_ivt+0x7c00 | ||
784 | //////////////////////////////////////////////////////////////////// | ||
785 | // 0x7c00 Entry 64 (size 16 bundles) Reserved | ||
786 | KVM_FAULT(64) | ||
787 | |||
788 | .org kvm_ia64_ivt+0x7d00 | ||
789 | ///////////////////////////////////////////////////////////////////// | ||
790 | // 0x7d00 Entry 65 (size 16 bundles) Reserved | ||
791 | KVM_FAULT(65) | ||
792 | |||
793 | .org kvm_ia64_ivt+0x7e00 | ||
794 | ///////////////////////////////////////////////////////////////////// | ||
795 | // 0x7e00 Entry 66 (size 16 bundles) Reserved | ||
796 | KVM_FAULT(66) | ||
797 | |||
798 | .org kvm_ia64_ivt+0x7f00 | ||
799 | //////////////////////////////////////////////////////////////////// | ||
800 | // 0x7f00 Entry 67 (size 16 bundles) Reserved | ||
801 | KVM_FAULT(67) | ||
802 | |||
803 | .org kvm_ia64_ivt+0x8000 | ||
804 | // There is no particular reason for this code to be here, other than that | ||
805 | // there happens to be space here that would go unused otherwise. If this | ||
806 | // fault ever gets "unreserved", simply moved the following code to a more | ||
807 | // suitable spot... | ||
808 | |||
809 | |||
810 | ENTRY(kvm_dtlb_miss_dispatch) | ||
811 | mov r19 = 2 | ||
812 | KVM_SAVE_MIN_WITH_COVER_R19 | ||
813 | alloc r14=ar.pfs,0,0,3,0 | ||
814 | mov out0=cr.ifa | ||
815 | mov out1=r15 | ||
816 | adds r3=8,r2 // set up second base pointer | ||
817 | ;; | ||
818 | ssm psr.ic | ||
819 | ;; | ||
820 | srlz.i // guarantee that interruption collection is on | ||
821 | ;; | ||
822 | (p15) ssm psr.i // restore psr.i | ||
823 | addl r14=@gprel(ia64_leave_hypervisor_prepare),gp | ||
824 | ;; | ||
825 | KVM_SAVE_REST | ||
826 | KVM_SAVE_EXTRA | ||
827 | mov rp=r14 | ||
828 | ;; | ||
829 | adds out2=16,r12 | ||
830 | br.call.sptk.many b6=kvm_page_fault | ||
831 | END(kvm_dtlb_miss_dispatch) | ||
832 | |||
833 | ENTRY(kvm_itlb_miss_dispatch) | ||
834 | |||
835 | KVM_SAVE_MIN_WITH_COVER_R19 | ||
836 | alloc r14=ar.pfs,0,0,3,0 | ||
837 | mov out0=cr.ifa | ||
838 | mov out1=r15 | ||
839 | adds r3=8,r2 // set up second base pointer | ||
840 | ;; | ||
841 | ssm psr.ic | ||
842 | ;; | ||
843 | srlz.i // guarantee that interruption collection is on | ||
844 | ;; | ||
845 | (p15) ssm psr.i // restore psr.i | ||
846 | addl r14=@gprel(ia64_leave_hypervisor),gp | ||
847 | ;; | ||
848 | KVM_SAVE_REST | ||
849 | mov rp=r14 | ||
850 | ;; | ||
851 | adds out2=16,r12 | ||
852 | br.call.sptk.many b6=kvm_page_fault | ||
853 | END(kvm_itlb_miss_dispatch) | ||
854 | |||
855 | ENTRY(kvm_dispatch_reflection) | ||
856 | /* | ||
857 | * Input: | ||
858 | * psr.ic: off | ||
859 | * r19: intr type (offset into ivt, see ia64_int.h) | ||
860 | * r31: contains saved predicates (pr) | ||
861 | */ | ||
862 | KVM_SAVE_MIN_WITH_COVER_R19 | ||
863 | alloc r14=ar.pfs,0,0,5,0 | ||
864 | mov out0=cr.ifa | ||
865 | mov out1=cr.isr | ||
866 | mov out2=cr.iim | ||
867 | mov out3=r15 | ||
868 | adds r3=8,r2 // set up second base pointer | ||
869 | ;; | ||
870 | ssm psr.ic | ||
871 | ;; | ||
872 | srlz.i // guarantee that interruption collection is on | ||
873 | ;; | ||
874 | (p15) ssm psr.i // restore psr.i | ||
875 | addl r14=@gprel(ia64_leave_hypervisor),gp | ||
876 | ;; | ||
877 | KVM_SAVE_REST | ||
878 | mov rp=r14 | ||
879 | ;; | ||
880 | adds out4=16,r12 | ||
881 | br.call.sptk.many b6=reflect_interruption | ||
882 | END(kvm_dispatch_reflection) | ||
883 | |||
884 | ENTRY(kvm_dispatch_virtualization_fault) | ||
885 | adds r16 = VMM_VCPU_CAUSE_OFFSET,r21 | ||
886 | adds r17 = VMM_VCPU_OPCODE_OFFSET,r21 | ||
887 | ;; | ||
888 | st8 [r16] = r24 | ||
889 | st8 [r17] = r25 | ||
890 | ;; | ||
891 | KVM_SAVE_MIN_WITH_COVER_R19 | ||
892 | ;; | ||
893 | alloc r14=ar.pfs,0,0,2,0 // (must be first in insn group!) | ||
894 | mov out0=r13 //vcpu | ||
895 | adds r3=8,r2 // set up second base pointer | ||
896 | ;; | ||
897 | ssm psr.ic | ||
898 | ;; | ||
899 | srlz.i // guarantee that interruption collection is on | ||
900 | ;; | ||
901 | (p15) ssm psr.i // restore psr.i | ||
902 | addl r14=@gprel(ia64_leave_hypervisor_prepare),gp | ||
903 | ;; | ||
904 | KVM_SAVE_REST | ||
905 | KVM_SAVE_EXTRA | ||
906 | mov rp=r14 | ||
907 | ;; | ||
908 | adds out1=16,sp //regs | ||
909 | br.call.sptk.many b6=kvm_emulate | ||
910 | END(kvm_dispatch_virtualization_fault) | ||
911 | |||
912 | |||
913 | ENTRY(kvm_dispatch_interrupt) | ||
914 | KVM_SAVE_MIN_WITH_COVER_R19 // uses r31; defines r2 and r3 | ||
915 | ;; | ||
916 | alloc r14=ar.pfs,0,0,1,0 // must be first in an insn group | ||
917 | adds r3=8,r2 // set up second base pointer for SAVE_REST | ||
918 | ;; | ||
919 | ssm psr.ic | ||
920 | ;; | ||
921 | srlz.i | ||
922 | ;; | ||
923 | (p15) ssm psr.i | ||
924 | addl r14=@gprel(ia64_leave_hypervisor),gp | ||
925 | ;; | ||
926 | KVM_SAVE_REST | ||
927 | mov rp=r14 | ||
928 | ;; | ||
929 | mov out0=r13 // pass pointer to pt_regs as second arg | ||
930 | br.call.sptk.many b6=kvm_ia64_handle_irq | ||
931 | END(kvm_dispatch_interrupt) | ||
932 | |||
933 | GLOBAL_ENTRY(ia64_leave_nested) | ||
934 | rsm psr.i | ||
935 | ;; | ||
936 | adds r21=PT(PR)+16,r12 | ||
937 | ;; | ||
938 | lfetch [r21],PT(CR_IPSR)-PT(PR) | ||
939 | adds r2=PT(B6)+16,r12 | ||
940 | adds r3=PT(R16)+16,r12 | ||
941 | ;; | ||
942 | lfetch [r21] | ||
943 | ld8 r28=[r2],8 // load b6 | ||
944 | adds r29=PT(R24)+16,r12 | ||
945 | |||
946 | ld8.fill r16=[r3] | ||
947 | adds r3=PT(AR_CSD)-PT(R16),r3 | ||
948 | adds r30=PT(AR_CCV)+16,r12 | ||
949 | ;; | ||
950 | ld8.fill r24=[r29] | ||
951 | ld8 r15=[r30] // load ar.ccv | ||
952 | ;; | ||
953 | ld8 r29=[r2],16 // load b7 | ||
954 | ld8 r30=[r3],16 // load ar.csd | ||
955 | ;; | ||
956 | ld8 r31=[r2],16 // load ar.ssd | ||
957 | ld8.fill r8=[r3],16 | ||
958 | ;; | ||
959 | ld8.fill r9=[r2],16 | ||
960 | ld8.fill r10=[r3],PT(R17)-PT(R10) | ||
961 | ;; | ||
962 | ld8.fill r11=[r2],PT(R18)-PT(R11) | ||
963 | ld8.fill r17=[r3],16 | ||
964 | ;; | ||
965 | ld8.fill r18=[r2],16 | ||
966 | ld8.fill r19=[r3],16 | ||
967 | ;; | ||
968 | ld8.fill r20=[r2],16 | ||
969 | ld8.fill r21=[r3],16 | ||
970 | mov ar.csd=r30 | ||
971 | mov ar.ssd=r31 | ||
972 | ;; | ||
973 | rsm psr.i | psr.ic | ||
974 | // initiate turning off of interrupt and interruption collection | ||
975 | invala // invalidate ALAT | ||
976 | ;; | ||
977 | srlz.i | ||
978 | ;; | ||
979 | ld8.fill r22=[r2],24 | ||
980 | ld8.fill r23=[r3],24 | ||
981 | mov b6=r28 | ||
982 | ;; | ||
983 | ld8.fill r25=[r2],16 | ||
984 | ld8.fill r26=[r3],16 | ||
985 | mov b7=r29 | ||
986 | ;; | ||
987 | ld8.fill r27=[r2],16 | ||
988 | ld8.fill r28=[r3],16 | ||
989 | ;; | ||
990 | ld8.fill r29=[r2],16 | ||
991 | ld8.fill r30=[r3],24 | ||
992 | ;; | ||
993 | ld8.fill r31=[r2],PT(F9)-PT(R31) | ||
994 | adds r3=PT(F10)-PT(F6),r3 | ||
995 | ;; | ||
996 | ldf.fill f9=[r2],PT(F6)-PT(F9) | ||
997 | ldf.fill f10=[r3],PT(F8)-PT(F10) | ||
998 | ;; | ||
999 | ldf.fill f6=[r2],PT(F7)-PT(F6) | ||
1000 | ;; | ||
1001 | ldf.fill f7=[r2],PT(F11)-PT(F7) | ||
1002 | ldf.fill f8=[r3],32 | ||
1003 | ;; | ||
1004 | srlz.i // ensure interruption collection is off | ||
1005 | mov ar.ccv=r15 | ||
1006 | ;; | ||
1007 | bsw.0 // switch back to bank 0 (no stop bit required beforehand...) | ||
1008 | ;; | ||
1009 | ldf.fill f11=[r2] | ||
1010 | // mov r18=r13 | ||
1011 | // mov r21=r13 | ||
1012 | adds r16=PT(CR_IPSR)+16,r12 | ||
1013 | adds r17=PT(CR_IIP)+16,r12 | ||
1014 | ;; | ||
1015 | ld8 r29=[r16],16 // load cr.ipsr | ||
1016 | ld8 r28=[r17],16 // load cr.iip | ||
1017 | ;; | ||
1018 | ld8 r30=[r16],16 // load cr.ifs | ||
1019 | ld8 r25=[r17],16 // load ar.unat | ||
1020 | ;; | ||
1021 | ld8 r26=[r16],16 // load ar.pfs | ||
1022 | ld8 r27=[r17],16 // load ar.rsc | ||
1023 | cmp.eq p9,p0=r0,r0 | ||
1024 | // set p9 to indicate that we should restore cr.ifs | ||
1025 | ;; | ||
1026 | ld8 r24=[r16],16 // load ar.rnat (may be garbage) | ||
1027 | ld8 r23=[r17],16// load ar.bspstore (may be garbage) | ||
1028 | ;; | ||
1029 | ld8 r31=[r16],16 // load predicates | ||
1030 | ld8 r22=[r17],16 // load b0 | ||
1031 | ;; | ||
1032 | ld8 r19=[r16],16 // load ar.rsc value for "loadrs" | ||
1033 | ld8.fill r1=[r17],16 // load r1 | ||
1034 | ;; | ||
1035 | ld8.fill r12=[r16],16 | ||
1036 | ld8.fill r13=[r17],16 | ||
1037 | ;; | ||
1038 | ld8 r20=[r16],16 // ar.fpsr | ||
1039 | ld8.fill r15=[r17],16 | ||
1040 | ;; | ||
1041 | ld8.fill r14=[r16],16 | ||
1042 | ld8.fill r2=[r17] | ||
1043 | ;; | ||
1044 | ld8.fill r3=[r16] | ||
1045 | ;; | ||
1046 | mov r16=ar.bsp // get existing backing store pointer | ||
1047 | ;; | ||
1048 | mov b0=r22 | ||
1049 | mov ar.pfs=r26 | ||
1050 | mov cr.ifs=r30 | ||
1051 | mov cr.ipsr=r29 | ||
1052 | mov ar.fpsr=r20 | ||
1053 | mov cr.iip=r28 | ||
1054 | ;; | ||
1055 | mov ar.rsc=r27 | ||
1056 | mov ar.unat=r25 | ||
1057 | mov pr=r31,-1 | ||
1058 | rfi | ||
1059 | END(ia64_leave_nested) | ||
1060 | |||
1061 | GLOBAL_ENTRY(ia64_leave_hypervisor_prepare) | ||
1062 | /* | ||
1063 | * work.need_resched etc. mustn't get changed | ||
1064 | *by this CPU before it returns to | ||
1065 | * user- or fsys-mode, hence we disable interrupts early on: | ||
1066 | */ | ||
1067 | adds r2 = PT(R4)+16,r12 | ||
1068 | adds r3 = PT(R5)+16,r12 | ||
1069 | adds r8 = PT(EML_UNAT)+16,r12 | ||
1070 | ;; | ||
1071 | ld8 r8 = [r8] | ||
1072 | ;; | ||
1073 | mov ar.unat=r8 | ||
1074 | ;; | ||
1075 | ld8.fill r4=[r2],16 //load r4 | ||
1076 | ld8.fill r5=[r3],16 //load r5 | ||
1077 | ;; | ||
1078 | ld8.fill r6=[r2] //load r6 | ||
1079 | ld8.fill r7=[r3] //load r7 | ||
1080 | ;; | ||
1081 | END(ia64_leave_hypervisor_prepare) | ||
1082 | //fall through | ||
1083 | GLOBAL_ENTRY(ia64_leave_hypervisor) | ||
1084 | rsm psr.i | ||
1085 | ;; | ||
1086 | br.call.sptk.many b0=leave_hypervisor_tail | ||
1087 | ;; | ||
1088 | adds r20=PT(PR)+16,r12 | ||
1089 | adds r8=PT(EML_UNAT)+16,r12 | ||
1090 | ;; | ||
1091 | ld8 r8=[r8] | ||
1092 | ;; | ||
1093 | mov ar.unat=r8 | ||
1094 | ;; | ||
1095 | lfetch [r20],PT(CR_IPSR)-PT(PR) | ||
1096 | adds r2 = PT(B6)+16,r12 | ||
1097 | adds r3 = PT(B7)+16,r12 | ||
1098 | ;; | ||
1099 | lfetch [r20] | ||
1100 | ;; | ||
1101 | ld8 r24=[r2],16 /* B6 */ | ||
1102 | ld8 r25=[r3],16 /* B7 */ | ||
1103 | ;; | ||
1104 | ld8 r26=[r2],16 /* ar_csd */ | ||
1105 | ld8 r27=[r3],16 /* ar_ssd */ | ||
1106 | mov b6 = r24 | ||
1107 | ;; | ||
1108 | ld8.fill r8=[r2],16 | ||
1109 | ld8.fill r9=[r3],16 | ||
1110 | mov b7 = r25 | ||
1111 | ;; | ||
1112 | mov ar.csd = r26 | ||
1113 | mov ar.ssd = r27 | ||
1114 | ;; | ||
1115 | ld8.fill r10=[r2],PT(R15)-PT(R10) | ||
1116 | ld8.fill r11=[r3],PT(R14)-PT(R11) | ||
1117 | ;; | ||
1118 | ld8.fill r15=[r2],PT(R16)-PT(R15) | ||
1119 | ld8.fill r14=[r3],PT(R17)-PT(R14) | ||
1120 | ;; | ||
1121 | ld8.fill r16=[r2],16 | ||
1122 | ld8.fill r17=[r3],16 | ||
1123 | ;; | ||
1124 | ld8.fill r18=[r2],16 | ||
1125 | ld8.fill r19=[r3],16 | ||
1126 | ;; | ||
1127 | ld8.fill r20=[r2],16 | ||
1128 | ld8.fill r21=[r3],16 | ||
1129 | ;; | ||
1130 | ld8.fill r22=[r2],16 | ||
1131 | ld8.fill r23=[r3],16 | ||
1132 | ;; | ||
1133 | ld8.fill r24=[r2],16 | ||
1134 | ld8.fill r25=[r3],16 | ||
1135 | ;; | ||
1136 | ld8.fill r26=[r2],16 | ||
1137 | ld8.fill r27=[r3],16 | ||
1138 | ;; | ||
1139 | ld8.fill r28=[r2],16 | ||
1140 | ld8.fill r29=[r3],16 | ||
1141 | ;; | ||
1142 | ld8.fill r30=[r2],PT(F6)-PT(R30) | ||
1143 | ld8.fill r31=[r3],PT(F7)-PT(R31) | ||
1144 | ;; | ||
1145 | rsm psr.i | psr.ic | ||
1146 | // initiate turning off of interrupt and interruption collection | ||
1147 | invala // invalidate ALAT | ||
1148 | ;; | ||
1149 | srlz.i // ensure interruption collection is off | ||
1150 | ;; | ||
1151 | bsw.0 | ||
1152 | ;; | ||
1153 | adds r16 = PT(CR_IPSR)+16,r12 | ||
1154 | adds r17 = PT(CR_IIP)+16,r12 | ||
1155 | mov r21=r13 // get current | ||
1156 | ;; | ||
1157 | ld8 r31=[r16],16 // load cr.ipsr | ||
1158 | ld8 r30=[r17],16 // load cr.iip | ||
1159 | ;; | ||
1160 | ld8 r29=[r16],16 // load cr.ifs | ||
1161 | ld8 r28=[r17],16 // load ar.unat | ||
1162 | ;; | ||
1163 | ld8 r27=[r16],16 // load ar.pfs | ||
1164 | ld8 r26=[r17],16 // load ar.rsc | ||
1165 | ;; | ||
1166 | ld8 r25=[r16],16 // load ar.rnat | ||
1167 | ld8 r24=[r17],16 // load ar.bspstore | ||
1168 | ;; | ||
1169 | ld8 r23=[r16],16 // load predicates | ||
1170 | ld8 r22=[r17],16 // load b0 | ||
1171 | ;; | ||
1172 | ld8 r20=[r16],16 // load ar.rsc value for "loadrs" | ||
1173 | ld8.fill r1=[r17],16 //load r1 | ||
1174 | ;; | ||
1175 | ld8.fill r12=[r16],16 //load r12 | ||
1176 | ld8.fill r13=[r17],PT(R2)-PT(R13) //load r13 | ||
1177 | ;; | ||
1178 | ld8 r19=[r16],PT(R3)-PT(AR_FPSR) //load ar_fpsr | ||
1179 | ld8.fill r2=[r17],PT(AR_CCV)-PT(R2) //load r2 | ||
1180 | ;; | ||
1181 | ld8.fill r3=[r16] //load r3 | ||
1182 | ld8 r18=[r17] //load ar_ccv | ||
1183 | ;; | ||
1184 | mov ar.fpsr=r19 | ||
1185 | mov ar.ccv=r18 | ||
1186 | shr.u r18=r20,16 | ||
1187 | ;; | ||
1188 | kvm_rbs_switch: | ||
1189 | mov r19=96 | ||
1190 | |||
1191 | kvm_dont_preserve_current_frame: | ||
1192 | /* | ||
1193 | * To prevent leaking bits between the hypervisor and guest domain, | ||
1194 | * we must clear the stacked registers in the "invalid" partition here. | ||
1195 | * 5 registers/cycle on McKinley). | ||
1196 | */ | ||
1197 | # define pRecurse p6 | ||
1198 | # define pReturn p7 | ||
1199 | # define Nregs 14 | ||
1200 | |||
1201 | alloc loc0=ar.pfs,2,Nregs-2,2,0 | ||
1202 | shr.u loc1=r18,9 // RNaTslots <= floor(dirtySize / (64*8)) | ||
1203 | sub r19=r19,r18 // r19 = (physStackedSize + 8) - dirtySize | ||
1204 | ;; | ||
1205 | mov ar.rsc=r20 // load ar.rsc to be used for "loadrs" | ||
1206 | shladd in0=loc1,3,r19 | ||
1207 | mov in1=0 | ||
1208 | ;; | ||
1209 | TEXT_ALIGN(32) | ||
1210 | kvm_rse_clear_invalid: | ||
1211 | alloc loc0=ar.pfs,2,Nregs-2,2,0 | ||
1212 | cmp.lt pRecurse,p0=Nregs*8,in0 | ||
1213 | // if more than Nregs regs left to clear, (re)curse | ||
1214 | add out0=-Nregs*8,in0 | ||
1215 | add out1=1,in1 // increment recursion count | ||
1216 | mov loc1=0 | ||
1217 | mov loc2=0 | ||
1218 | ;; | ||
1219 | mov loc3=0 | ||
1220 | mov loc4=0 | ||
1221 | mov loc5=0 | ||
1222 | mov loc6=0 | ||
1223 | mov loc7=0 | ||
1224 | (pRecurse) br.call.dptk.few b0=kvm_rse_clear_invalid | ||
1225 | ;; | ||
1226 | mov loc8=0 | ||
1227 | mov loc9=0 | ||
1228 | cmp.ne pReturn,p0=r0,in1 | ||
1229 | // if recursion count != 0, we need to do a br.ret | ||
1230 | mov loc10=0 | ||
1231 | mov loc11=0 | ||
1232 | (pReturn) br.ret.dptk.many b0 | ||
1233 | |||
1234 | # undef pRecurse | ||
1235 | # undef pReturn | ||
1236 | |||
1237 | // loadrs has already been shifted | ||
1238 | alloc r16=ar.pfs,0,0,0,0 // drop current register frame | ||
1239 | ;; | ||
1240 | loadrs | ||
1241 | ;; | ||
1242 | mov ar.bspstore=r24 | ||
1243 | ;; | ||
1244 | mov ar.unat=r28 | ||
1245 | mov ar.rnat=r25 | ||
1246 | mov ar.rsc=r26 | ||
1247 | ;; | ||
1248 | mov cr.ipsr=r31 | ||
1249 | mov cr.iip=r30 | ||
1250 | mov cr.ifs=r29 | ||
1251 | mov ar.pfs=r27 | ||
1252 | adds r18=VMM_VPD_BASE_OFFSET,r21 | ||
1253 | ;; | ||
1254 | ld8 r18=[r18] //vpd | ||
1255 | adds r17=VMM_VCPU_ISR_OFFSET,r21 | ||
1256 | ;; | ||
1257 | ld8 r17=[r17] | ||
1258 | adds r19=VMM_VPD_VPSR_OFFSET,r18 | ||
1259 | ;; | ||
1260 | ld8 r19=[r19] //vpsr | ||
1261 | mov r25=r18 | ||
1262 | adds r16= VMM_VCPU_GP_OFFSET,r21 | ||
1263 | ;; | ||
1264 | ld8 r16= [r16] // Put gp in r24 | ||
1265 | movl r24=@gprel(ia64_vmm_entry) // calculate return address | ||
1266 | ;; | ||
1267 | add r24=r24,r16 | ||
1268 | ;; | ||
1269 | br.sptk.many kvm_vps_sync_write // call the service | ||
1270 | ;; | ||
1271 | END(ia64_leave_hypervisor) | ||
1272 | // fall through | ||
1273 | GLOBAL_ENTRY(ia64_vmm_entry) | ||
1274 | /* | ||
1275 | * must be at bank 0 | ||
1276 | * parameter: | ||
1277 | * r17:cr.isr | ||
1278 | * r18:vpd | ||
1279 | * r19:vpsr | ||
1280 | * r22:b0 | ||
1281 | * r23:predicate | ||
1282 | */ | ||
1283 | mov r24=r22 | ||
1284 | mov r25=r18 | ||
1285 | tbit.nz p1,p2 = r19,IA64_PSR_IC_BIT // p1=vpsr.ic | ||
1286 | (p1) br.cond.sptk.few kvm_vps_resume_normal | ||
1287 | (p2) br.cond.sptk.many kvm_vps_resume_handler | ||
1288 | ;; | ||
1289 | END(ia64_vmm_entry) | ||
1290 | |||
1291 | /* | ||
1292 | * extern u64 ia64_call_vsa(u64 proc, u64 arg1, u64 arg2, | ||
1293 | * u64 arg3, u64 arg4, u64 arg5, | ||
1294 | * u64 arg6, u64 arg7); | ||
1295 | * | ||
1296 | * XXX: The currently defined services use only 4 args at the max. The | ||
1297 | * rest are not consumed. | ||
1298 | */ | ||
1299 | GLOBAL_ENTRY(ia64_call_vsa) | ||
1300 | .regstk 4,4,0,0 | ||
1301 | |||
1302 | rpsave = loc0 | ||
1303 | pfssave = loc1 | ||
1304 | psrsave = loc2 | ||
1305 | entry = loc3 | ||
1306 | hostret = r24 | ||
1307 | |||
1308 | alloc pfssave=ar.pfs,4,4,0,0 | ||
1309 | mov rpsave=rp | ||
1310 | adds entry=VMM_VCPU_VSA_BASE_OFFSET, r13 | ||
1311 | ;; | ||
1312 | ld8 entry=[entry] | ||
1313 | 1: mov hostret=ip | ||
1314 | mov r25=in1 // copy arguments | ||
1315 | mov r26=in2 | ||
1316 | mov r27=in3 | ||
1317 | mov psrsave=psr | ||
1318 | ;; | ||
1319 | tbit.nz p6,p0=psrsave,14 // IA64_PSR_I | ||
1320 | tbit.nz p7,p0=psrsave,13 // IA64_PSR_IC | ||
1321 | ;; | ||
1322 | add hostret=2f-1b,hostret // calculate return address | ||
1323 | add entry=entry,in0 | ||
1324 | ;; | ||
1325 | rsm psr.i | psr.ic | ||
1326 | ;; | ||
1327 | srlz.i | ||
1328 | mov b6=entry | ||
1329 | br.cond.sptk b6 // call the service | ||
1330 | 2: | ||
1331 | // Architectural sequence for enabling interrupts if necessary | ||
1332 | (p7) ssm psr.ic | ||
1333 | ;; | ||
1334 | (p7) srlz.i | ||
1335 | ;; | ||
1336 | (p6) ssm psr.i | ||
1337 | ;; | ||
1338 | mov rp=rpsave | ||
1339 | mov ar.pfs=pfssave | ||
1340 | mov r8=r31 | ||
1341 | ;; | ||
1342 | srlz.d | ||
1343 | br.ret.sptk rp | ||
1344 | |||
1345 | END(ia64_call_vsa) | ||
1346 | |||
1347 | #define INIT_BSPSTORE ((4<<30)-(12<<20)-0x100) | ||
1348 | |||
1349 | GLOBAL_ENTRY(vmm_reset_entry) | ||
1350 | //set up ipsr, iip, vpd.vpsr, dcr | ||
1351 | // For IPSR: it/dt/rt=1, i/ic=1, si=1, vm/bn=1 | ||
1352 | // For DCR: all bits 0 | ||
1353 | bsw.0 | ||
1354 | ;; | ||
1355 | mov r21 =r13 | ||
1356 | adds r14=-VMM_PT_REGS_SIZE, r12 | ||
1357 | ;; | ||
1358 | movl r6=0x501008826000 // IPSR dt/rt/it:1;i/ic:1, si:1, vm/bn:1 | ||
1359 | movl r10=0x8000000000000000 | ||
1360 | adds r16=PT(CR_IIP), r14 | ||
1361 | adds r20=PT(R1), r14 | ||
1362 | ;; | ||
1363 | rsm psr.ic | psr.i | ||
1364 | ;; | ||
1365 | srlz.i | ||
1366 | ;; | ||
1367 | mov ar.rsc = 0 | ||
1368 | ;; | ||
1369 | flushrs | ||
1370 | ;; | ||
1371 | mov ar.bspstore = 0 | ||
1372 | // clear BSPSTORE | ||
1373 | ;; | ||
1374 | mov cr.ipsr=r6 | ||
1375 | mov cr.ifs=r10 | ||
1376 | ld8 r4 = [r16] // Set init iip for first run. | ||
1377 | ld8 r1 = [r20] | ||
1378 | ;; | ||
1379 | mov cr.iip=r4 | ||
1380 | adds r16=VMM_VPD_BASE_OFFSET,r13 | ||
1381 | ;; | ||
1382 | ld8 r18=[r16] | ||
1383 | ;; | ||
1384 | adds r19=VMM_VPD_VPSR_OFFSET,r18 | ||
1385 | ;; | ||
1386 | ld8 r19=[r19] | ||
1387 | mov r17=r0 | ||
1388 | mov r22=r0 | ||
1389 | mov r23=r0 | ||
1390 | br.cond.sptk ia64_vmm_entry | ||
1391 | br.ret.sptk b0 | ||
1392 | END(vmm_reset_entry) | ||
diff --git a/arch/ia64/kvm/vti.h b/arch/ia64/kvm/vti.h deleted file mode 100644 index b214b5b0432d..000000000000 --- a/arch/ia64/kvm/vti.h +++ /dev/null | |||
@@ -1,290 +0,0 @@ | |||
1 | /* | ||
2 | * vti.h: prototype for generial vt related interface | ||
3 | * Copyright (c) 2004, Intel Corporation. | ||
4 | * | ||
5 | * Xuefei Xu (Anthony Xu) (anthony.xu@intel.com) | ||
6 | * Fred Yang (fred.yang@intel.com) | ||
7 | * Kun Tian (Kevin Tian) (kevin.tian@intel.com) | ||
8 | * | ||
9 | * Copyright (c) 2007, Intel Corporation. | ||
10 | * Zhang xiantao <xiantao.zhang@intel.com> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify it | ||
13 | * under the terms and conditions of the GNU General Public License, | ||
14 | * version 2, as published by the Free Software Foundation. | ||
15 | * | ||
16 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
17 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
19 | * more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License along with | ||
22 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | ||
23 | * Place - Suite 330, Boston, MA 02111-1307 USA. | ||
24 | */ | ||
25 | #ifndef _KVM_VT_I_H | ||
26 | #define _KVM_VT_I_H | ||
27 | |||
28 | #ifndef __ASSEMBLY__ | ||
29 | #include <asm/page.h> | ||
30 | |||
31 | #include <linux/kvm_host.h> | ||
32 | |||
33 | /* define itr.i and itr.d in ia64_itr function */ | ||
34 | #define ITR 0x01 | ||
35 | #define DTR 0x02 | ||
36 | #define IaDTR 0x03 | ||
37 | |||
38 | #define IA64_TR_VMM 6 /*itr6, dtr6 : maps vmm code, vmbuffer*/ | ||
39 | #define IA64_TR_VM_DATA 7 /*dtr7 : maps current vm data*/ | ||
40 | |||
41 | #define RR6 (6UL<<61) | ||
42 | #define RR7 (7UL<<61) | ||
43 | |||
44 | |||
45 | /* config_options in pal_vp_init_env */ | ||
46 | #define VP_INITIALIZE 1UL | ||
47 | #define VP_FR_PMC 1UL<<1 | ||
48 | #define VP_OPCODE 1UL<<8 | ||
49 | #define VP_CAUSE 1UL<<9 | ||
50 | #define VP_FW_ACC 1UL<<63 | ||
51 | |||
52 | /* init vp env with initializing vm_buffer */ | ||
53 | #define VP_INIT_ENV_INITALIZE (VP_INITIALIZE | VP_FR_PMC |\ | ||
54 | VP_OPCODE | VP_CAUSE | VP_FW_ACC) | ||
55 | /* init vp env without initializing vm_buffer */ | ||
56 | #define VP_INIT_ENV VP_FR_PMC | VP_OPCODE | VP_CAUSE | VP_FW_ACC | ||
57 | |||
58 | #define PAL_VP_CREATE 265 | ||
59 | /* Stacked Virt. Initializes a new VPD for the operation of | ||
60 | * a new virtual processor in the virtual environment. | ||
61 | */ | ||
62 | #define PAL_VP_ENV_INFO 266 | ||
63 | /*Stacked Virt. Returns the parameters needed to enter a virtual environment.*/ | ||
64 | #define PAL_VP_EXIT_ENV 267 | ||
65 | /*Stacked Virt. Allows a logical processor to exit a virtual environment.*/ | ||
66 | #define PAL_VP_INIT_ENV 268 | ||
67 | /*Stacked Virt. Allows a logical processor to enter a virtual environment.*/ | ||
68 | #define PAL_VP_REGISTER 269 | ||
69 | /*Stacked Virt. Register a different host IVT for the virtual processor.*/ | ||
70 | #define PAL_VP_RESUME 270 | ||
71 | /* Renamed from PAL_VP_RESUME */ | ||
72 | #define PAL_VP_RESTORE 270 | ||
73 | /*Stacked Virt. Resumes virtual processor operation on the logical processor.*/ | ||
74 | #define PAL_VP_SUSPEND 271 | ||
75 | /* Renamed from PAL_VP_SUSPEND */ | ||
76 | #define PAL_VP_SAVE 271 | ||
77 | /* Stacked Virt. Suspends operation for the specified virtual processor on | ||
78 | * the logical processor. | ||
79 | */ | ||
80 | #define PAL_VP_TERMINATE 272 | ||
81 | /* Stacked Virt. Terminates operation for the specified virtual processor.*/ | ||
82 | |||
83 | union vac { | ||
84 | unsigned long value; | ||
85 | struct { | ||
86 | unsigned int a_int:1; | ||
87 | unsigned int a_from_int_cr:1; | ||
88 | unsigned int a_to_int_cr:1; | ||
89 | unsigned int a_from_psr:1; | ||
90 | unsigned int a_from_cpuid:1; | ||
91 | unsigned int a_cover:1; | ||
92 | unsigned int a_bsw:1; | ||
93 | long reserved:57; | ||
94 | }; | ||
95 | }; | ||
96 | |||
97 | union vdc { | ||
98 | unsigned long value; | ||
99 | struct { | ||
100 | unsigned int d_vmsw:1; | ||
101 | unsigned int d_extint:1; | ||
102 | unsigned int d_ibr_dbr:1; | ||
103 | unsigned int d_pmc:1; | ||
104 | unsigned int d_to_pmd:1; | ||
105 | unsigned int d_itm:1; | ||
106 | long reserved:58; | ||
107 | }; | ||
108 | }; | ||
109 | |||
110 | struct vpd { | ||
111 | union vac vac; | ||
112 | union vdc vdc; | ||
113 | unsigned long virt_env_vaddr; | ||
114 | unsigned long reserved1[29]; | ||
115 | unsigned long vhpi; | ||
116 | unsigned long reserved2[95]; | ||
117 | unsigned long vgr[16]; | ||
118 | unsigned long vbgr[16]; | ||
119 | unsigned long vnat; | ||
120 | unsigned long vbnat; | ||
121 | unsigned long vcpuid[5]; | ||
122 | unsigned long reserved3[11]; | ||
123 | unsigned long vpsr; | ||
124 | unsigned long vpr; | ||
125 | unsigned long reserved4[76]; | ||
126 | union { | ||
127 | unsigned long vcr[128]; | ||
128 | struct { | ||
129 | unsigned long dcr; | ||
130 | unsigned long itm; | ||
131 | unsigned long iva; | ||
132 | unsigned long rsv1[5]; | ||
133 | unsigned long pta; | ||
134 | unsigned long rsv2[7]; | ||
135 | unsigned long ipsr; | ||
136 | unsigned long isr; | ||
137 | unsigned long rsv3; | ||
138 | unsigned long iip; | ||
139 | unsigned long ifa; | ||
140 | unsigned long itir; | ||
141 | unsigned long iipa; | ||
142 | unsigned long ifs; | ||
143 | unsigned long iim; | ||
144 | unsigned long iha; | ||
145 | unsigned long rsv4[38]; | ||
146 | unsigned long lid; | ||
147 | unsigned long ivr; | ||
148 | unsigned long tpr; | ||
149 | unsigned long eoi; | ||
150 | unsigned long irr[4]; | ||
151 | unsigned long itv; | ||
152 | unsigned long pmv; | ||
153 | unsigned long cmcv; | ||
154 | unsigned long rsv5[5]; | ||
155 | unsigned long lrr0; | ||
156 | unsigned long lrr1; | ||
157 | unsigned long rsv6[46]; | ||
158 | }; | ||
159 | }; | ||
160 | unsigned long reserved5[128]; | ||
161 | unsigned long reserved6[3456]; | ||
162 | unsigned long vmm_avail[128]; | ||
163 | unsigned long reserved7[4096]; | ||
164 | }; | ||
165 | |||
166 | #define PAL_PROC_VM_BIT (1UL << 40) | ||
167 | #define PAL_PROC_VMSW_BIT (1UL << 54) | ||
168 | |||
169 | static inline s64 ia64_pal_vp_env_info(u64 *buffer_size, | ||
170 | u64 *vp_env_info) | ||
171 | { | ||
172 | struct ia64_pal_retval iprv; | ||
173 | PAL_CALL_STK(iprv, PAL_VP_ENV_INFO, 0, 0, 0); | ||
174 | *buffer_size = iprv.v0; | ||
175 | *vp_env_info = iprv.v1; | ||
176 | return iprv.status; | ||
177 | } | ||
178 | |||
179 | static inline s64 ia64_pal_vp_exit_env(u64 iva) | ||
180 | { | ||
181 | struct ia64_pal_retval iprv; | ||
182 | |||
183 | PAL_CALL_STK(iprv, PAL_VP_EXIT_ENV, (u64)iva, 0, 0); | ||
184 | return iprv.status; | ||
185 | } | ||
186 | |||
187 | static inline s64 ia64_pal_vp_init_env(u64 config_options, u64 pbase_addr, | ||
188 | u64 vbase_addr, u64 *vsa_base) | ||
189 | { | ||
190 | struct ia64_pal_retval iprv; | ||
191 | |||
192 | PAL_CALL_STK(iprv, PAL_VP_INIT_ENV, config_options, pbase_addr, | ||
193 | vbase_addr); | ||
194 | *vsa_base = iprv.v0; | ||
195 | |||
196 | return iprv.status; | ||
197 | } | ||
198 | |||
199 | static inline s64 ia64_pal_vp_restore(u64 *vpd, u64 pal_proc_vector) | ||
200 | { | ||
201 | struct ia64_pal_retval iprv; | ||
202 | |||
203 | PAL_CALL_STK(iprv, PAL_VP_RESTORE, (u64)vpd, pal_proc_vector, 0); | ||
204 | |||
205 | return iprv.status; | ||
206 | } | ||
207 | |||
208 | static inline s64 ia64_pal_vp_save(u64 *vpd, u64 pal_proc_vector) | ||
209 | { | ||
210 | struct ia64_pal_retval iprv; | ||
211 | |||
212 | PAL_CALL_STK(iprv, PAL_VP_SAVE, (u64)vpd, pal_proc_vector, 0); | ||
213 | |||
214 | return iprv.status; | ||
215 | } | ||
216 | |||
217 | #endif | ||
218 | |||
219 | /*VPD field offset*/ | ||
220 | #define VPD_VAC_START_OFFSET 0 | ||
221 | #define VPD_VDC_START_OFFSET 8 | ||
222 | #define VPD_VHPI_START_OFFSET 256 | ||
223 | #define VPD_VGR_START_OFFSET 1024 | ||
224 | #define VPD_VBGR_START_OFFSET 1152 | ||
225 | #define VPD_VNAT_START_OFFSET 1280 | ||
226 | #define VPD_VBNAT_START_OFFSET 1288 | ||
227 | #define VPD_VCPUID_START_OFFSET 1296 | ||
228 | #define VPD_VPSR_START_OFFSET 1424 | ||
229 | #define VPD_VPR_START_OFFSET 1432 | ||
230 | #define VPD_VRSE_CFLE_START_OFFSET 1440 | ||
231 | #define VPD_VCR_START_OFFSET 2048 | ||
232 | #define VPD_VTPR_START_OFFSET 2576 | ||
233 | #define VPD_VRR_START_OFFSET 3072 | ||
234 | #define VPD_VMM_VAIL_START_OFFSET 31744 | ||
235 | |||
236 | /*Virtualization faults*/ | ||
237 | |||
238 | #define EVENT_MOV_TO_AR 1 | ||
239 | #define EVENT_MOV_TO_AR_IMM 2 | ||
240 | #define EVENT_MOV_FROM_AR 3 | ||
241 | #define EVENT_MOV_TO_CR 4 | ||
242 | #define EVENT_MOV_FROM_CR 5 | ||
243 | #define EVENT_MOV_TO_PSR 6 | ||
244 | #define EVENT_MOV_FROM_PSR 7 | ||
245 | #define EVENT_ITC_D 8 | ||
246 | #define EVENT_ITC_I 9 | ||
247 | #define EVENT_MOV_TO_RR 10 | ||
248 | #define EVENT_MOV_TO_DBR 11 | ||
249 | #define EVENT_MOV_TO_IBR 12 | ||
250 | #define EVENT_MOV_TO_PKR 13 | ||
251 | #define EVENT_MOV_TO_PMC 14 | ||
252 | #define EVENT_MOV_TO_PMD 15 | ||
253 | #define EVENT_ITR_D 16 | ||
254 | #define EVENT_ITR_I 17 | ||
255 | #define EVENT_MOV_FROM_RR 18 | ||
256 | #define EVENT_MOV_FROM_DBR 19 | ||
257 | #define EVENT_MOV_FROM_IBR 20 | ||
258 | #define EVENT_MOV_FROM_PKR 21 | ||
259 | #define EVENT_MOV_FROM_PMC 22 | ||
260 | #define EVENT_MOV_FROM_CPUID 23 | ||
261 | #define EVENT_SSM 24 | ||
262 | #define EVENT_RSM 25 | ||
263 | #define EVENT_PTC_L 26 | ||
264 | #define EVENT_PTC_G 27 | ||
265 | #define EVENT_PTC_GA 28 | ||
266 | #define EVENT_PTR_D 29 | ||
267 | #define EVENT_PTR_I 30 | ||
268 | #define EVENT_THASH 31 | ||
269 | #define EVENT_TTAG 32 | ||
270 | #define EVENT_TPA 33 | ||
271 | #define EVENT_TAK 34 | ||
272 | #define EVENT_PTC_E 35 | ||
273 | #define EVENT_COVER 36 | ||
274 | #define EVENT_RFI 37 | ||
275 | #define EVENT_BSW_0 38 | ||
276 | #define EVENT_BSW_1 39 | ||
277 | #define EVENT_VMSW 40 | ||
278 | |||
279 | /**PAL virtual services offsets */ | ||
280 | #define PAL_VPS_RESUME_NORMAL 0x0000 | ||
281 | #define PAL_VPS_RESUME_HANDLER 0x0400 | ||
282 | #define PAL_VPS_SYNC_READ 0x0800 | ||
283 | #define PAL_VPS_SYNC_WRITE 0x0c00 | ||
284 | #define PAL_VPS_SET_PENDING_INTERRUPT 0x1000 | ||
285 | #define PAL_VPS_THASH 0x1400 | ||
286 | #define PAL_VPS_TTAG 0x1800 | ||
287 | #define PAL_VPS_RESTORE 0x1c00 | ||
288 | #define PAL_VPS_SAVE 0x2000 | ||
289 | |||
290 | #endif/* _VT_I_H*/ | ||
diff --git a/arch/ia64/kvm/vtlb.c b/arch/ia64/kvm/vtlb.c deleted file mode 100644 index a7869f8f49a6..000000000000 --- a/arch/ia64/kvm/vtlb.c +++ /dev/null | |||
@@ -1,640 +0,0 @@ | |||
1 | /* | ||
2 | * vtlb.c: guest virtual tlb handling module. | ||
3 | * Copyright (c) 2004, Intel Corporation. | ||
4 | * Yaozu Dong (Eddie Dong) <Eddie.dong@intel.com> | ||
5 | * Xuefei Xu (Anthony Xu) <anthony.xu@intel.com> | ||
6 | * | ||
7 | * Copyright (c) 2007, Intel Corporation. | ||
8 | * Xuefei Xu (Anthony Xu) <anthony.xu@intel.com> | ||
9 | * Xiantao Zhang <xiantao.zhang@intel.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms and conditions of the GNU General Public License, | ||
13 | * version 2, as published by the Free Software Foundation. | ||
14 | * | ||
15 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
16 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
18 | * more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License along with | ||
21 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | ||
22 | * Place - Suite 330, Boston, MA 02111-1307 USA. | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #include "vcpu.h" | ||
27 | |||
28 | #include <linux/rwsem.h> | ||
29 | |||
30 | #include <asm/tlb.h> | ||
31 | |||
32 | /* | ||
33 | * Check to see if the address rid:va is translated by the TLB | ||
34 | */ | ||
35 | |||
36 | static int __is_tr_translated(struct thash_data *trp, u64 rid, u64 va) | ||
37 | { | ||
38 | return ((trp->p) && (trp->rid == rid) | ||
39 | && ((va-trp->vadr) < PSIZE(trp->ps))); | ||
40 | } | ||
41 | |||
42 | /* | ||
43 | * Only for GUEST TR format. | ||
44 | */ | ||
45 | static int __is_tr_overlap(struct thash_data *trp, u64 rid, u64 sva, u64 eva) | ||
46 | { | ||
47 | u64 sa1, ea1; | ||
48 | |||
49 | if (!trp->p || trp->rid != rid) | ||
50 | return 0; | ||
51 | |||
52 | sa1 = trp->vadr; | ||
53 | ea1 = sa1 + PSIZE(trp->ps) - 1; | ||
54 | eva -= 1; | ||
55 | if ((sva > ea1) || (sa1 > eva)) | ||
56 | return 0; | ||
57 | else | ||
58 | return 1; | ||
59 | |||
60 | } | ||
61 | |||
62 | void machine_tlb_purge(u64 va, u64 ps) | ||
63 | { | ||
64 | ia64_ptcl(va, ps << 2); | ||
65 | } | ||
66 | |||
67 | void local_flush_tlb_all(void) | ||
68 | { | ||
69 | int i, j; | ||
70 | unsigned long flags, count0, count1; | ||
71 | unsigned long stride0, stride1, addr; | ||
72 | |||
73 | addr = current_vcpu->arch.ptce_base; | ||
74 | count0 = current_vcpu->arch.ptce_count[0]; | ||
75 | count1 = current_vcpu->arch.ptce_count[1]; | ||
76 | stride0 = current_vcpu->arch.ptce_stride[0]; | ||
77 | stride1 = current_vcpu->arch.ptce_stride[1]; | ||
78 | |||
79 | local_irq_save(flags); | ||
80 | for (i = 0; i < count0; ++i) { | ||
81 | for (j = 0; j < count1; ++j) { | ||
82 | ia64_ptce(addr); | ||
83 | addr += stride1; | ||
84 | } | ||
85 | addr += stride0; | ||
86 | } | ||
87 | local_irq_restore(flags); | ||
88 | ia64_srlz_i(); /* srlz.i implies srlz.d */ | ||
89 | } | ||
90 | |||
91 | int vhpt_enabled(struct kvm_vcpu *vcpu, u64 vadr, enum vhpt_ref ref) | ||
92 | { | ||
93 | union ia64_rr vrr; | ||
94 | union ia64_pta vpta; | ||
95 | struct ia64_psr vpsr; | ||
96 | |||
97 | vpsr = *(struct ia64_psr *)&VCPU(vcpu, vpsr); | ||
98 | vrr.val = vcpu_get_rr(vcpu, vadr); | ||
99 | vpta.val = vcpu_get_pta(vcpu); | ||
100 | |||
101 | if (vrr.ve & vpta.ve) { | ||
102 | switch (ref) { | ||
103 | case DATA_REF: | ||
104 | case NA_REF: | ||
105 | return vpsr.dt; | ||
106 | case INST_REF: | ||
107 | return vpsr.dt && vpsr.it && vpsr.ic; | ||
108 | case RSE_REF: | ||
109 | return vpsr.dt && vpsr.rt; | ||
110 | |||
111 | } | ||
112 | } | ||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | struct thash_data *vsa_thash(union ia64_pta vpta, u64 va, u64 vrr, u64 *tag) | ||
117 | { | ||
118 | u64 index, pfn, rid, pfn_bits; | ||
119 | |||
120 | pfn_bits = vpta.size - 5 - 8; | ||
121 | pfn = REGION_OFFSET(va) >> _REGION_PAGE_SIZE(vrr); | ||
122 | rid = _REGION_ID(vrr); | ||
123 | index = ((rid & 0xff) << pfn_bits)|(pfn & ((1UL << pfn_bits) - 1)); | ||
124 | *tag = ((rid >> 8) & 0xffff) | ((pfn >> pfn_bits) << 16); | ||
125 | |||
126 | return (struct thash_data *)((vpta.base << PTA_BASE_SHIFT) + | ||
127 | (index << 5)); | ||
128 | } | ||
129 | |||
130 | struct thash_data *__vtr_lookup(struct kvm_vcpu *vcpu, u64 va, int type) | ||
131 | { | ||
132 | |||
133 | struct thash_data *trp; | ||
134 | int i; | ||
135 | u64 rid; | ||
136 | |||
137 | rid = vcpu_get_rr(vcpu, va); | ||
138 | rid = rid & RR_RID_MASK; | ||
139 | if (type == D_TLB) { | ||
140 | if (vcpu_quick_region_check(vcpu->arch.dtr_regions, va)) { | ||
141 | for (trp = (struct thash_data *)&vcpu->arch.dtrs, i = 0; | ||
142 | i < NDTRS; i++, trp++) { | ||
143 | if (__is_tr_translated(trp, rid, va)) | ||
144 | return trp; | ||
145 | } | ||
146 | } | ||
147 | } else { | ||
148 | if (vcpu_quick_region_check(vcpu->arch.itr_regions, va)) { | ||
149 | for (trp = (struct thash_data *)&vcpu->arch.itrs, i = 0; | ||
150 | i < NITRS; i++, trp++) { | ||
151 | if (__is_tr_translated(trp, rid, va)) | ||
152 | return trp; | ||
153 | } | ||
154 | } | ||
155 | } | ||
156 | |||
157 | return NULL; | ||
158 | } | ||
159 | |||
160 | static void vhpt_insert(u64 pte, u64 itir, u64 ifa, u64 gpte) | ||
161 | { | ||
162 | union ia64_rr rr; | ||
163 | struct thash_data *head; | ||
164 | unsigned long ps, gpaddr; | ||
165 | |||
166 | ps = itir_ps(itir); | ||
167 | rr.val = ia64_get_rr(ifa); | ||
168 | |||
169 | gpaddr = ((gpte & _PAGE_PPN_MASK) >> ps << ps) | | ||
170 | (ifa & ((1UL << ps) - 1)); | ||
171 | |||
172 | head = (struct thash_data *)ia64_thash(ifa); | ||
173 | head->etag = INVALID_TI_TAG; | ||
174 | ia64_mf(); | ||
175 | head->page_flags = pte & ~PAGE_FLAGS_RV_MASK; | ||
176 | head->itir = rr.ps << 2; | ||
177 | head->etag = ia64_ttag(ifa); | ||
178 | head->gpaddr = gpaddr; | ||
179 | } | ||
180 | |||
181 | void mark_pages_dirty(struct kvm_vcpu *v, u64 pte, u64 ps) | ||
182 | { | ||
183 | u64 i, dirty_pages = 1; | ||
184 | u64 base_gfn = (pte&_PAGE_PPN_MASK) >> PAGE_SHIFT; | ||
185 | vmm_spinlock_t *lock = __kvm_va(v->arch.dirty_log_lock_pa); | ||
186 | void *dirty_bitmap = (void *)KVM_MEM_DIRTY_LOG_BASE; | ||
187 | |||
188 | dirty_pages <<= ps <= PAGE_SHIFT ? 0 : ps - PAGE_SHIFT; | ||
189 | |||
190 | vmm_spin_lock(lock); | ||
191 | for (i = 0; i < dirty_pages; i++) { | ||
192 | /* avoid RMW */ | ||
193 | if (!test_bit(base_gfn + i, dirty_bitmap)) | ||
194 | set_bit(base_gfn + i , dirty_bitmap); | ||
195 | } | ||
196 | vmm_spin_unlock(lock); | ||
197 | } | ||
198 | |||
199 | void thash_vhpt_insert(struct kvm_vcpu *v, u64 pte, u64 itir, u64 va, int type) | ||
200 | { | ||
201 | u64 phy_pte, psr; | ||
202 | union ia64_rr mrr; | ||
203 | |||
204 | mrr.val = ia64_get_rr(va); | ||
205 | phy_pte = translate_phy_pte(&pte, itir, va); | ||
206 | |||
207 | if (itir_ps(itir) >= mrr.ps) { | ||
208 | vhpt_insert(phy_pte, itir, va, pte); | ||
209 | } else { | ||
210 | phy_pte &= ~PAGE_FLAGS_RV_MASK; | ||
211 | psr = ia64_clear_ic(); | ||
212 | ia64_itc(type, va, phy_pte, itir_ps(itir)); | ||
213 | paravirt_dv_serialize_data(); | ||
214 | ia64_set_psr(psr); | ||
215 | } | ||
216 | |||
217 | if (!(pte&VTLB_PTE_IO)) | ||
218 | mark_pages_dirty(v, pte, itir_ps(itir)); | ||
219 | } | ||
220 | |||
221 | /* | ||
222 | * vhpt lookup | ||
223 | */ | ||
224 | struct thash_data *vhpt_lookup(u64 va) | ||
225 | { | ||
226 | struct thash_data *head; | ||
227 | u64 tag; | ||
228 | |||
229 | head = (struct thash_data *)ia64_thash(va); | ||
230 | tag = ia64_ttag(va); | ||
231 | if (head->etag == tag) | ||
232 | return head; | ||
233 | return NULL; | ||
234 | } | ||
235 | |||
236 | u64 guest_vhpt_lookup(u64 iha, u64 *pte) | ||
237 | { | ||
238 | u64 ret; | ||
239 | struct thash_data *data; | ||
240 | |||
241 | data = __vtr_lookup(current_vcpu, iha, D_TLB); | ||
242 | if (data != NULL) | ||
243 | thash_vhpt_insert(current_vcpu, data->page_flags, | ||
244 | data->itir, iha, D_TLB); | ||
245 | |||
246 | asm volatile ("rsm psr.ic|psr.i;;" | ||
247 | "srlz.d;;" | ||
248 | "ld8.s r9=[%1];;" | ||
249 | "tnat.nz p6,p7=r9;;" | ||
250 | "(p6) mov %0=1;" | ||
251 | "(p6) mov r9=r0;" | ||
252 | "(p7) extr.u r9=r9,0,53;;" | ||
253 | "(p7) mov %0=r0;" | ||
254 | "(p7) st8 [%2]=r9;;" | ||
255 | "ssm psr.ic;;" | ||
256 | "srlz.d;;" | ||
257 | "ssm psr.i;;" | ||
258 | "srlz.d;;" | ||
259 | : "=&r"(ret) : "r"(iha), "r"(pte) : "memory"); | ||
260 | |||
261 | return ret; | ||
262 | } | ||
263 | |||
264 | /* | ||
265 | * purge software guest tlb | ||
266 | */ | ||
267 | |||
268 | static void vtlb_purge(struct kvm_vcpu *v, u64 va, u64 ps) | ||
269 | { | ||
270 | struct thash_data *cur; | ||
271 | u64 start, curadr, size, psbits, tag, rr_ps, num; | ||
272 | union ia64_rr vrr; | ||
273 | struct thash_cb *hcb = &v->arch.vtlb; | ||
274 | |||
275 | vrr.val = vcpu_get_rr(v, va); | ||
276 | psbits = VMX(v, psbits[(va >> 61)]); | ||
277 | start = va & ~((1UL << ps) - 1); | ||
278 | while (psbits) { | ||
279 | curadr = start; | ||
280 | rr_ps = __ffs(psbits); | ||
281 | psbits &= ~(1UL << rr_ps); | ||
282 | num = 1UL << ((ps < rr_ps) ? 0 : (ps - rr_ps)); | ||
283 | size = PSIZE(rr_ps); | ||
284 | vrr.ps = rr_ps; | ||
285 | while (num) { | ||
286 | cur = vsa_thash(hcb->pta, curadr, vrr.val, &tag); | ||
287 | if (cur->etag == tag && cur->ps == rr_ps) | ||
288 | cur->etag = INVALID_TI_TAG; | ||
289 | curadr += size; | ||
290 | num--; | ||
291 | } | ||
292 | } | ||
293 | } | ||
294 | |||
295 | |||
296 | /* | ||
297 | * purge VHPT and machine TLB | ||
298 | */ | ||
299 | static void vhpt_purge(struct kvm_vcpu *v, u64 va, u64 ps) | ||
300 | { | ||
301 | struct thash_data *cur; | ||
302 | u64 start, size, tag, num; | ||
303 | union ia64_rr rr; | ||
304 | |||
305 | start = va & ~((1UL << ps) - 1); | ||
306 | rr.val = ia64_get_rr(va); | ||
307 | size = PSIZE(rr.ps); | ||
308 | num = 1UL << ((ps < rr.ps) ? 0 : (ps - rr.ps)); | ||
309 | while (num) { | ||
310 | cur = (struct thash_data *)ia64_thash(start); | ||
311 | tag = ia64_ttag(start); | ||
312 | if (cur->etag == tag) | ||
313 | cur->etag = INVALID_TI_TAG; | ||
314 | start += size; | ||
315 | num--; | ||
316 | } | ||
317 | machine_tlb_purge(va, ps); | ||
318 | } | ||
319 | |||
320 | /* | ||
321 | * Insert an entry into hash TLB or VHPT. | ||
322 | * NOTES: | ||
323 | * 1: When inserting VHPT to thash, "va" is a must covered | ||
324 | * address by the inserted machine VHPT entry. | ||
325 | * 2: The format of entry is always in TLB. | ||
326 | * 3: The caller need to make sure the new entry will not overlap | ||
327 | * with any existed entry. | ||
328 | */ | ||
329 | void vtlb_insert(struct kvm_vcpu *v, u64 pte, u64 itir, u64 va) | ||
330 | { | ||
331 | struct thash_data *head; | ||
332 | union ia64_rr vrr; | ||
333 | u64 tag; | ||
334 | struct thash_cb *hcb = &v->arch.vtlb; | ||
335 | |||
336 | vrr.val = vcpu_get_rr(v, va); | ||
337 | vrr.ps = itir_ps(itir); | ||
338 | VMX(v, psbits[va >> 61]) |= (1UL << vrr.ps); | ||
339 | head = vsa_thash(hcb->pta, va, vrr.val, &tag); | ||
340 | head->page_flags = pte; | ||
341 | head->itir = itir; | ||
342 | head->etag = tag; | ||
343 | } | ||
344 | |||
345 | int vtr_find_overlap(struct kvm_vcpu *vcpu, u64 va, u64 ps, int type) | ||
346 | { | ||
347 | struct thash_data *trp; | ||
348 | int i; | ||
349 | u64 end, rid; | ||
350 | |||
351 | rid = vcpu_get_rr(vcpu, va); | ||
352 | rid = rid & RR_RID_MASK; | ||
353 | end = va + PSIZE(ps); | ||
354 | if (type == D_TLB) { | ||
355 | if (vcpu_quick_region_check(vcpu->arch.dtr_regions, va)) { | ||
356 | for (trp = (struct thash_data *)&vcpu->arch.dtrs, i = 0; | ||
357 | i < NDTRS; i++, trp++) { | ||
358 | if (__is_tr_overlap(trp, rid, va, end)) | ||
359 | return i; | ||
360 | } | ||
361 | } | ||
362 | } else { | ||
363 | if (vcpu_quick_region_check(vcpu->arch.itr_regions, va)) { | ||
364 | for (trp = (struct thash_data *)&vcpu->arch.itrs, i = 0; | ||
365 | i < NITRS; i++, trp++) { | ||
366 | if (__is_tr_overlap(trp, rid, va, end)) | ||
367 | return i; | ||
368 | } | ||
369 | } | ||
370 | } | ||
371 | return -1; | ||
372 | } | ||
373 | |||
374 | /* | ||
375 | * Purge entries in VTLB and VHPT | ||
376 | */ | ||
377 | void thash_purge_entries(struct kvm_vcpu *v, u64 va, u64 ps) | ||
378 | { | ||
379 | if (vcpu_quick_region_check(v->arch.tc_regions, va)) | ||
380 | vtlb_purge(v, va, ps); | ||
381 | vhpt_purge(v, va, ps); | ||
382 | } | ||
383 | |||
384 | void thash_purge_entries_remote(struct kvm_vcpu *v, u64 va, u64 ps) | ||
385 | { | ||
386 | u64 old_va = va; | ||
387 | va = REGION_OFFSET(va); | ||
388 | if (vcpu_quick_region_check(v->arch.tc_regions, old_va)) | ||
389 | vtlb_purge(v, va, ps); | ||
390 | vhpt_purge(v, va, ps); | ||
391 | } | ||
392 | |||
393 | u64 translate_phy_pte(u64 *pte, u64 itir, u64 va) | ||
394 | { | ||
395 | u64 ps, ps_mask, paddr, maddr, io_mask; | ||
396 | union pte_flags phy_pte; | ||
397 | |||
398 | ps = itir_ps(itir); | ||
399 | ps_mask = ~((1UL << ps) - 1); | ||
400 | phy_pte.val = *pte; | ||
401 | paddr = *pte; | ||
402 | paddr = ((paddr & _PAGE_PPN_MASK) & ps_mask) | (va & ~ps_mask); | ||
403 | maddr = kvm_get_mpt_entry(paddr >> PAGE_SHIFT); | ||
404 | io_mask = maddr & GPFN_IO_MASK; | ||
405 | if (io_mask && (io_mask != GPFN_PHYS_MMIO)) { | ||
406 | *pte |= VTLB_PTE_IO; | ||
407 | return -1; | ||
408 | } | ||
409 | maddr = ((maddr & _PAGE_PPN_MASK) & PAGE_MASK) | | ||
410 | (paddr & ~PAGE_MASK); | ||
411 | phy_pte.ppn = maddr >> ARCH_PAGE_SHIFT; | ||
412 | return phy_pte.val; | ||
413 | } | ||
414 | |||
415 | /* | ||
416 | * Purge overlap TCs and then insert the new entry to emulate itc ops. | ||
417 | * Notes: Only TC entry can purge and insert. | ||
418 | */ | ||
419 | void thash_purge_and_insert(struct kvm_vcpu *v, u64 pte, u64 itir, | ||
420 | u64 ifa, int type) | ||
421 | { | ||
422 | u64 ps; | ||
423 | u64 phy_pte, io_mask, index; | ||
424 | union ia64_rr vrr, mrr; | ||
425 | |||
426 | ps = itir_ps(itir); | ||
427 | vrr.val = vcpu_get_rr(v, ifa); | ||
428 | mrr.val = ia64_get_rr(ifa); | ||
429 | |||
430 | index = (pte & _PAGE_PPN_MASK) >> PAGE_SHIFT; | ||
431 | io_mask = kvm_get_mpt_entry(index) & GPFN_IO_MASK; | ||
432 | phy_pte = translate_phy_pte(&pte, itir, ifa); | ||
433 | |||
434 | /* Ensure WB attribute if pte is related to a normal mem page, | ||
435 | * which is required by vga acceleration since qemu maps shared | ||
436 | * vram buffer with WB. | ||
437 | */ | ||
438 | if (!(pte & VTLB_PTE_IO) && ((pte & _PAGE_MA_MASK) != _PAGE_MA_NAT) && | ||
439 | io_mask != GPFN_PHYS_MMIO) { | ||
440 | pte &= ~_PAGE_MA_MASK; | ||
441 | phy_pte &= ~_PAGE_MA_MASK; | ||
442 | } | ||
443 | |||
444 | vtlb_purge(v, ifa, ps); | ||
445 | vhpt_purge(v, ifa, ps); | ||
446 | |||
447 | if ((ps != mrr.ps) || (pte & VTLB_PTE_IO)) { | ||
448 | vtlb_insert(v, pte, itir, ifa); | ||
449 | vcpu_quick_region_set(VMX(v, tc_regions), ifa); | ||
450 | } | ||
451 | if (pte & VTLB_PTE_IO) | ||
452 | return; | ||
453 | |||
454 | if (ps >= mrr.ps) | ||
455 | vhpt_insert(phy_pte, itir, ifa, pte); | ||
456 | else { | ||
457 | u64 psr; | ||
458 | phy_pte &= ~PAGE_FLAGS_RV_MASK; | ||
459 | psr = ia64_clear_ic(); | ||
460 | ia64_itc(type, ifa, phy_pte, ps); | ||
461 | paravirt_dv_serialize_data(); | ||
462 | ia64_set_psr(psr); | ||
463 | } | ||
464 | if (!(pte&VTLB_PTE_IO)) | ||
465 | mark_pages_dirty(v, pte, ps); | ||
466 | |||
467 | } | ||
468 | |||
469 | /* | ||
470 | * Purge all TCs or VHPT entries including those in Hash table. | ||
471 | * | ||
472 | */ | ||
473 | |||
474 | void thash_purge_all(struct kvm_vcpu *v) | ||
475 | { | ||
476 | int i; | ||
477 | struct thash_data *head; | ||
478 | struct thash_cb *vtlb, *vhpt; | ||
479 | vtlb = &v->arch.vtlb; | ||
480 | vhpt = &v->arch.vhpt; | ||
481 | |||
482 | for (i = 0; i < 8; i++) | ||
483 | VMX(v, psbits[i]) = 0; | ||
484 | |||
485 | head = vtlb->hash; | ||
486 | for (i = 0; i < vtlb->num; i++) { | ||
487 | head->page_flags = 0; | ||
488 | head->etag = INVALID_TI_TAG; | ||
489 | head->itir = 0; | ||
490 | head->next = 0; | ||
491 | head++; | ||
492 | }; | ||
493 | |||
494 | head = vhpt->hash; | ||
495 | for (i = 0; i < vhpt->num; i++) { | ||
496 | head->page_flags = 0; | ||
497 | head->etag = INVALID_TI_TAG; | ||
498 | head->itir = 0; | ||
499 | head->next = 0; | ||
500 | head++; | ||
501 | }; | ||
502 | |||
503 | local_flush_tlb_all(); | ||
504 | } | ||
505 | |||
506 | /* | ||
507 | * Lookup the hash table and its collision chain to find an entry | ||
508 | * covering this address rid:va or the entry. | ||
509 | * | ||
510 | * INPUT: | ||
511 | * in: TLB format for both VHPT & TLB. | ||
512 | */ | ||
513 | struct thash_data *vtlb_lookup(struct kvm_vcpu *v, u64 va, int is_data) | ||
514 | { | ||
515 | struct thash_data *cch; | ||
516 | u64 psbits, ps, tag; | ||
517 | union ia64_rr vrr; | ||
518 | |||
519 | struct thash_cb *hcb = &v->arch.vtlb; | ||
520 | |||
521 | cch = __vtr_lookup(v, va, is_data); | ||
522 | if (cch) | ||
523 | return cch; | ||
524 | |||
525 | if (vcpu_quick_region_check(v->arch.tc_regions, va) == 0) | ||
526 | return NULL; | ||
527 | |||
528 | psbits = VMX(v, psbits[(va >> 61)]); | ||
529 | vrr.val = vcpu_get_rr(v, va); | ||
530 | while (psbits) { | ||
531 | ps = __ffs(psbits); | ||
532 | psbits &= ~(1UL << ps); | ||
533 | vrr.ps = ps; | ||
534 | cch = vsa_thash(hcb->pta, va, vrr.val, &tag); | ||
535 | if (cch->etag == tag && cch->ps == ps) | ||
536 | return cch; | ||
537 | } | ||
538 | |||
539 | return NULL; | ||
540 | } | ||
541 | |||
542 | /* | ||
543 | * Initialize internal control data before service. | ||
544 | */ | ||
545 | void thash_init(struct thash_cb *hcb, u64 sz) | ||
546 | { | ||
547 | int i; | ||
548 | struct thash_data *head; | ||
549 | |||
550 | hcb->pta.val = (unsigned long)hcb->hash; | ||
551 | hcb->pta.vf = 1; | ||
552 | hcb->pta.ve = 1; | ||
553 | hcb->pta.size = sz; | ||
554 | head = hcb->hash; | ||
555 | for (i = 0; i < hcb->num; i++) { | ||
556 | head->page_flags = 0; | ||
557 | head->itir = 0; | ||
558 | head->etag = INVALID_TI_TAG; | ||
559 | head->next = 0; | ||
560 | head++; | ||
561 | } | ||
562 | } | ||
563 | |||
564 | u64 kvm_get_mpt_entry(u64 gpfn) | ||
565 | { | ||
566 | u64 *base = (u64 *) KVM_P2M_BASE; | ||
567 | |||
568 | if (gpfn >= (KVM_P2M_SIZE >> 3)) | ||
569 | panic_vm(current_vcpu, "Invalid gpfn =%lx\n", gpfn); | ||
570 | |||
571 | return *(base + gpfn); | ||
572 | } | ||
573 | |||
574 | u64 kvm_lookup_mpa(u64 gpfn) | ||
575 | { | ||
576 | u64 maddr; | ||
577 | maddr = kvm_get_mpt_entry(gpfn); | ||
578 | return maddr&_PAGE_PPN_MASK; | ||
579 | } | ||
580 | |||
581 | u64 kvm_gpa_to_mpa(u64 gpa) | ||
582 | { | ||
583 | u64 pte = kvm_lookup_mpa(gpa >> PAGE_SHIFT); | ||
584 | return (pte >> PAGE_SHIFT << PAGE_SHIFT) | (gpa & ~PAGE_MASK); | ||
585 | } | ||
586 | |||
587 | /* | ||
588 | * Fetch guest bundle code. | ||
589 | * INPUT: | ||
590 | * gip: guest ip | ||
591 | * pbundle: used to return fetched bundle. | ||
592 | */ | ||
593 | int fetch_code(struct kvm_vcpu *vcpu, u64 gip, IA64_BUNDLE *pbundle) | ||
594 | { | ||
595 | u64 gpip = 0; /* guest physical IP*/ | ||
596 | u64 *vpa; | ||
597 | struct thash_data *tlb; | ||
598 | u64 maddr; | ||
599 | |||
600 | if (!(VCPU(vcpu, vpsr) & IA64_PSR_IT)) { | ||
601 | /* I-side physical mode */ | ||
602 | gpip = gip; | ||
603 | } else { | ||
604 | tlb = vtlb_lookup(vcpu, gip, I_TLB); | ||
605 | if (tlb) | ||
606 | gpip = (tlb->ppn >> (tlb->ps - 12) << tlb->ps) | | ||
607 | (gip & (PSIZE(tlb->ps) - 1)); | ||
608 | } | ||
609 | if (gpip) { | ||
610 | maddr = kvm_gpa_to_mpa(gpip); | ||
611 | } else { | ||
612 | tlb = vhpt_lookup(gip); | ||
613 | if (tlb == NULL) { | ||
614 | ia64_ptcl(gip, ARCH_PAGE_SHIFT << 2); | ||
615 | return IA64_FAULT; | ||
616 | } | ||
617 | maddr = (tlb->ppn >> (tlb->ps - 12) << tlb->ps) | ||
618 | | (gip & (PSIZE(tlb->ps) - 1)); | ||
619 | } | ||
620 | vpa = (u64 *)__kvm_va(maddr); | ||
621 | |||
622 | pbundle->i64[0] = *vpa++; | ||
623 | pbundle->i64[1] = *vpa; | ||
624 | |||
625 | return IA64_NO_FAULT; | ||
626 | } | ||
627 | |||
628 | void kvm_init_vhpt(struct kvm_vcpu *v) | ||
629 | { | ||
630 | v->arch.vhpt.num = VHPT_NUM_ENTRIES; | ||
631 | thash_init(&v->arch.vhpt, VHPT_SHIFT); | ||
632 | ia64_set_pta(v->arch.vhpt.pta.val); | ||
633 | /*Enable VHPT here?*/ | ||
634 | } | ||
635 | |||
636 | void kvm_init_vtlb(struct kvm_vcpu *v) | ||
637 | { | ||
638 | v->arch.vtlb.num = VTLB_NUM_ENTRIES; | ||
639 | thash_init(&v->arch.vtlb, VTLB_SHIFT); | ||
640 | } | ||
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index 6acf0c2a0f99..942c7b1678e3 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h | |||
@@ -170,8 +170,6 @@ extern void *kvmppc_pin_guest_page(struct kvm *kvm, unsigned long addr, | |||
170 | unsigned long *nb_ret); | 170 | unsigned long *nb_ret); |
171 | extern void kvmppc_unpin_guest_page(struct kvm *kvm, void *addr, | 171 | extern void kvmppc_unpin_guest_page(struct kvm *kvm, void *addr, |
172 | unsigned long gpa, bool dirty); | 172 | unsigned long gpa, bool dirty); |
173 | extern long kvmppc_virtmode_h_enter(struct kvm_vcpu *vcpu, unsigned long flags, | ||
174 | long pte_index, unsigned long pteh, unsigned long ptel); | ||
175 | extern long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, | 173 | extern long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, |
176 | long pte_index, unsigned long pteh, unsigned long ptel, | 174 | long pte_index, unsigned long pteh, unsigned long ptel, |
177 | pgd_t *pgdir, bool realmode, unsigned long *idx_ret); | 175 | pgd_t *pgdir, bool realmode, unsigned long *idx_ret); |
diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h index 0aa817933e6a..2d81e202bdcc 100644 --- a/arch/powerpc/include/asm/kvm_book3s_64.h +++ b/arch/powerpc/include/asm/kvm_book3s_64.h | |||
@@ -37,7 +37,6 @@ static inline void svcpu_put(struct kvmppc_book3s_shadow_vcpu *svcpu) | |||
37 | 37 | ||
38 | #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE | 38 | #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE |
39 | #define KVM_DEFAULT_HPT_ORDER 24 /* 16MB HPT by default */ | 39 | #define KVM_DEFAULT_HPT_ORDER 24 /* 16MB HPT by default */ |
40 | extern unsigned long kvm_rma_pages; | ||
41 | #endif | 40 | #endif |
42 | 41 | ||
43 | #define VRMA_VSID 0x1ffffffUL /* 1TB VSID reserved for VRMA */ | 42 | #define VRMA_VSID 0x1ffffffUL /* 1TB VSID reserved for VRMA */ |
@@ -148,7 +147,7 @@ static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r, | |||
148 | /* This covers 14..54 bits of va*/ | 147 | /* This covers 14..54 bits of va*/ |
149 | rb = (v & ~0x7fUL) << 16; /* AVA field */ | 148 | rb = (v & ~0x7fUL) << 16; /* AVA field */ |
150 | 149 | ||
151 | rb |= v >> (62 - 8); /* B field */ | 150 | rb |= (v >> HPTE_V_SSIZE_SHIFT) << 8; /* B field */ |
152 | /* | 151 | /* |
153 | * AVA in v had cleared lower 23 bits. We need to derive | 152 | * AVA in v had cleared lower 23 bits. We need to derive |
154 | * that from pteg index | 153 | * that from pteg index |
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 047855619cc4..7efd666a3fa7 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h | |||
@@ -180,11 +180,6 @@ struct kvmppc_spapr_tce_table { | |||
180 | struct page *pages[0]; | 180 | struct page *pages[0]; |
181 | }; | 181 | }; |
182 | 182 | ||
183 | struct kvm_rma_info { | ||
184 | atomic_t use_count; | ||
185 | unsigned long base_pfn; | ||
186 | }; | ||
187 | |||
188 | /* XICS components, defined in book3s_xics.c */ | 183 | /* XICS components, defined in book3s_xics.c */ |
189 | struct kvmppc_xics; | 184 | struct kvmppc_xics; |
190 | struct kvmppc_icp; | 185 | struct kvmppc_icp; |
@@ -214,16 +209,9 @@ struct revmap_entry { | |||
214 | #define KVMPPC_RMAP_PRESENT 0x100000000ul | 209 | #define KVMPPC_RMAP_PRESENT 0x100000000ul |
215 | #define KVMPPC_RMAP_INDEX 0xfffffffful | 210 | #define KVMPPC_RMAP_INDEX 0xfffffffful |
216 | 211 | ||
217 | /* Low-order bits in memslot->arch.slot_phys[] */ | ||
218 | #define KVMPPC_PAGE_ORDER_MASK 0x1f | ||
219 | #define KVMPPC_PAGE_NO_CACHE HPTE_R_I /* 0x20 */ | ||
220 | #define KVMPPC_PAGE_WRITETHRU HPTE_R_W /* 0x40 */ | ||
221 | #define KVMPPC_GOT_PAGE 0x80 | ||
222 | |||
223 | struct kvm_arch_memory_slot { | 212 | struct kvm_arch_memory_slot { |
224 | #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE | 213 | #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE |
225 | unsigned long *rmap; | 214 | unsigned long *rmap; |
226 | unsigned long *slot_phys; | ||
227 | #endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */ | 215 | #endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */ |
228 | }; | 216 | }; |
229 | 217 | ||
@@ -242,14 +230,12 @@ struct kvm_arch { | |||
242 | struct kvm_rma_info *rma; | 230 | struct kvm_rma_info *rma; |
243 | unsigned long vrma_slb_v; | 231 | unsigned long vrma_slb_v; |
244 | int rma_setup_done; | 232 | int rma_setup_done; |
245 | int using_mmu_notifiers; | ||
246 | u32 hpt_order; | 233 | u32 hpt_order; |
247 | atomic_t vcpus_running; | 234 | atomic_t vcpus_running; |
248 | u32 online_vcores; | 235 | u32 online_vcores; |
249 | unsigned long hpt_npte; | 236 | unsigned long hpt_npte; |
250 | unsigned long hpt_mask; | 237 | unsigned long hpt_mask; |
251 | atomic_t hpte_mod_interest; | 238 | atomic_t hpte_mod_interest; |
252 | spinlock_t slot_phys_lock; | ||
253 | cpumask_t need_tlb_flush; | 239 | cpumask_t need_tlb_flush; |
254 | int hpt_cma_alloc; | 240 | int hpt_cma_alloc; |
255 | #endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */ | 241 | #endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */ |
@@ -297,6 +283,7 @@ struct kvmppc_vcore { | |||
297 | struct list_head runnable_threads; | 283 | struct list_head runnable_threads; |
298 | spinlock_t lock; | 284 | spinlock_t lock; |
299 | wait_queue_head_t wq; | 285 | wait_queue_head_t wq; |
286 | spinlock_t stoltb_lock; /* protects stolen_tb and preempt_tb */ | ||
300 | u64 stolen_tb; | 287 | u64 stolen_tb; |
301 | u64 preempt_tb; | 288 | u64 preempt_tb; |
302 | struct kvm_vcpu *runner; | 289 | struct kvm_vcpu *runner; |
@@ -308,6 +295,7 @@ struct kvmppc_vcore { | |||
308 | ulong dpdes; /* doorbell state (POWER8) */ | 295 | ulong dpdes; /* doorbell state (POWER8) */ |
309 | void *mpp_buffer; /* Micro Partition Prefetch buffer */ | 296 | void *mpp_buffer; /* Micro Partition Prefetch buffer */ |
310 | bool mpp_buffer_is_valid; | 297 | bool mpp_buffer_is_valid; |
298 | ulong conferring_threads; | ||
311 | }; | 299 | }; |
312 | 300 | ||
313 | #define VCORE_ENTRY_COUNT(vc) ((vc)->entry_exit_count & 0xff) | 301 | #define VCORE_ENTRY_COUNT(vc) ((vc)->entry_exit_count & 0xff) |
@@ -664,6 +652,8 @@ struct kvm_vcpu_arch { | |||
664 | spinlock_t tbacct_lock; | 652 | spinlock_t tbacct_lock; |
665 | u64 busy_stolen; | 653 | u64 busy_stolen; |
666 | u64 busy_preempt; | 654 | u64 busy_preempt; |
655 | |||
656 | u32 emul_inst; | ||
667 | #endif | 657 | #endif |
668 | }; | 658 | }; |
669 | 659 | ||
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index a6dcdb6d13c1..46bf652c9169 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h | |||
@@ -170,8 +170,6 @@ extern long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, | |||
170 | unsigned long ioba, unsigned long tce); | 170 | unsigned long ioba, unsigned long tce); |
171 | extern long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn, | 171 | extern long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn, |
172 | unsigned long ioba); | 172 | unsigned long ioba); |
173 | extern struct kvm_rma_info *kvm_alloc_rma(void); | ||
174 | extern void kvm_release_rma(struct kvm_rma_info *ri); | ||
175 | extern struct page *kvm_alloc_hpt(unsigned long nr_pages); | 173 | extern struct page *kvm_alloc_hpt(unsigned long nr_pages); |
176 | extern void kvm_release_hpt(struct page *page, unsigned long nr_pages); | 174 | extern void kvm_release_hpt(struct page *page, unsigned long nr_pages); |
177 | extern int kvmppc_core_init_vm(struct kvm *kvm); | 175 | extern int kvmppc_core_init_vm(struct kvm *kvm); |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index c161ef3f28a1..24d78e1871c9 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -489,7 +489,6 @@ int main(void) | |||
489 | DEFINE(KVM_HOST_LPID, offsetof(struct kvm, arch.host_lpid)); | 489 | DEFINE(KVM_HOST_LPID, offsetof(struct kvm, arch.host_lpid)); |
490 | DEFINE(KVM_HOST_LPCR, offsetof(struct kvm, arch.host_lpcr)); | 490 | DEFINE(KVM_HOST_LPCR, offsetof(struct kvm, arch.host_lpcr)); |
491 | DEFINE(KVM_HOST_SDR1, offsetof(struct kvm, arch.host_sdr1)); | 491 | DEFINE(KVM_HOST_SDR1, offsetof(struct kvm, arch.host_sdr1)); |
492 | DEFINE(KVM_TLBIE_LOCK, offsetof(struct kvm, arch.tlbie_lock)); | ||
493 | DEFINE(KVM_NEED_FLUSH, offsetof(struct kvm, arch.need_tlb_flush.bits)); | 492 | DEFINE(KVM_NEED_FLUSH, offsetof(struct kvm, arch.need_tlb_flush.bits)); |
494 | DEFINE(KVM_ENABLED_HCALLS, offsetof(struct kvm, arch.enabled_hcalls)); | 493 | DEFINE(KVM_ENABLED_HCALLS, offsetof(struct kvm, arch.enabled_hcalls)); |
495 | DEFINE(KVM_LPCR, offsetof(struct kvm, arch.lpcr)); | 494 | DEFINE(KVM_LPCR, offsetof(struct kvm, arch.lpcr)); |
@@ -499,6 +498,7 @@ int main(void) | |||
499 | DEFINE(VCPU_DAR, offsetof(struct kvm_vcpu, arch.shregs.dar)); | 498 | DEFINE(VCPU_DAR, offsetof(struct kvm_vcpu, arch.shregs.dar)); |
500 | DEFINE(VCPU_VPA, offsetof(struct kvm_vcpu, arch.vpa.pinned_addr)); | 499 | DEFINE(VCPU_VPA, offsetof(struct kvm_vcpu, arch.vpa.pinned_addr)); |
501 | DEFINE(VCPU_VPA_DIRTY, offsetof(struct kvm_vcpu, arch.vpa.dirty)); | 500 | DEFINE(VCPU_VPA_DIRTY, offsetof(struct kvm_vcpu, arch.vpa.dirty)); |
501 | DEFINE(VCPU_HEIR, offsetof(struct kvm_vcpu, arch.emul_inst)); | ||
502 | #endif | 502 | #endif |
503 | #ifdef CONFIG_PPC_BOOK3S | 503 | #ifdef CONFIG_PPC_BOOK3S |
504 | DEFINE(VCPU_VCPUID, offsetof(struct kvm_vcpu, vcpu_id)); | 504 | DEFINE(VCPU_VCPUID, offsetof(struct kvm_vcpu, vcpu_id)); |
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index 602eb51d20bc..f5769f19ae25 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig | |||
@@ -172,6 +172,7 @@ config KVM_XICS | |||
172 | depends on KVM_BOOK3S_64 && !KVM_MPIC | 172 | depends on KVM_BOOK3S_64 && !KVM_MPIC |
173 | select HAVE_KVM_IRQCHIP | 173 | select HAVE_KVM_IRQCHIP |
174 | select HAVE_KVM_IRQFD | 174 | select HAVE_KVM_IRQFD |
175 | default y | ||
175 | ---help--- | 176 | ---help--- |
176 | Include support for the XICS (eXternal Interrupt Controller | 177 | Include support for the XICS (eXternal Interrupt Controller |
177 | Specification) interrupt controller architecture used on | 178 | Specification) interrupt controller architecture used on |
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index b32db4b95361..888bf466d8c6 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c | |||
@@ -64,14 +64,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { | |||
64 | { NULL } | 64 | { NULL } |
65 | }; | 65 | }; |
66 | 66 | ||
67 | void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu) | ||
68 | { | ||
69 | } | ||
70 | |||
71 | void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu) | ||
72 | { | ||
73 | } | ||
74 | |||
75 | void kvmppc_unfixup_split_real(struct kvm_vcpu *vcpu) | 67 | void kvmppc_unfixup_split_real(struct kvm_vcpu *vcpu) |
76 | { | 68 | { |
77 | if (vcpu->arch.hflags & BOOK3S_HFLAG_SPLIT_HACK) { | 69 | if (vcpu->arch.hflags & BOOK3S_HFLAG_SPLIT_HACK) { |
diff --git a/arch/powerpc/kvm/book3s_32_mmu.c b/arch/powerpc/kvm/book3s_32_mmu.c index cd0b0730e29e..a2eb6d354a57 100644 --- a/arch/powerpc/kvm/book3s_32_mmu.c +++ b/arch/powerpc/kvm/book3s_32_mmu.c | |||
@@ -78,11 +78,6 @@ static inline bool sr_kp(u32 sr_raw) | |||
78 | return (sr_raw & 0x20000000) ? true: false; | 78 | return (sr_raw & 0x20000000) ? true: false; |
79 | } | 79 | } |
80 | 80 | ||
81 | static inline bool sr_nx(u32 sr_raw) | ||
82 | { | ||
83 | return (sr_raw & 0x10000000) ? true: false; | ||
84 | } | ||
85 | |||
86 | static int kvmppc_mmu_book3s_32_xlate_bat(struct kvm_vcpu *vcpu, gva_t eaddr, | 81 | static int kvmppc_mmu_book3s_32_xlate_bat(struct kvm_vcpu *vcpu, gva_t eaddr, |
87 | struct kvmppc_pte *pte, bool data, | 82 | struct kvmppc_pte *pte, bool data, |
88 | bool iswrite); | 83 | bool iswrite); |
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index d40770248b6a..534acb3c6c3d 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c | |||
@@ -37,8 +37,7 @@ | |||
37 | #include <asm/ppc-opcode.h> | 37 | #include <asm/ppc-opcode.h> |
38 | #include <asm/cputable.h> | 38 | #include <asm/cputable.h> |
39 | 39 | ||
40 | /* POWER7 has 10-bit LPIDs, PPC970 has 6-bit LPIDs */ | 40 | #include "trace_hv.h" |
41 | #define MAX_LPID_970 63 | ||
42 | 41 | ||
43 | /* Power architecture requires HPT is at least 256kB */ | 42 | /* Power architecture requires HPT is at least 256kB */ |
44 | #define PPC_MIN_HPT_ORDER 18 | 43 | #define PPC_MIN_HPT_ORDER 18 |
@@ -229,14 +228,9 @@ int kvmppc_mmu_hv_init(void) | |||
229 | if (!cpu_has_feature(CPU_FTR_HVMODE)) | 228 | if (!cpu_has_feature(CPU_FTR_HVMODE)) |
230 | return -EINVAL; | 229 | return -EINVAL; |
231 | 230 | ||
232 | /* POWER7 has 10-bit LPIDs, PPC970 and e500mc have 6-bit LPIDs */ | 231 | /* POWER7 has 10-bit LPIDs (12-bit in POWER8) */ |
233 | if (cpu_has_feature(CPU_FTR_ARCH_206)) { | 232 | host_lpid = mfspr(SPRN_LPID); |
234 | host_lpid = mfspr(SPRN_LPID); /* POWER7 */ | 233 | rsvd_lpid = LPID_RSVD; |
235 | rsvd_lpid = LPID_RSVD; | ||
236 | } else { | ||
237 | host_lpid = 0; /* PPC970 */ | ||
238 | rsvd_lpid = MAX_LPID_970; | ||
239 | } | ||
240 | 234 | ||
241 | kvmppc_init_lpid(rsvd_lpid + 1); | 235 | kvmppc_init_lpid(rsvd_lpid + 1); |
242 | 236 | ||
@@ -259,130 +253,12 @@ static void kvmppc_mmu_book3s_64_hv_reset_msr(struct kvm_vcpu *vcpu) | |||
259 | kvmppc_set_msr(vcpu, msr); | 253 | kvmppc_set_msr(vcpu, msr); |
260 | } | 254 | } |
261 | 255 | ||
262 | /* | ||
263 | * This is called to get a reference to a guest page if there isn't | ||
264 | * one already in the memslot->arch.slot_phys[] array. | ||
265 | */ | ||
266 | static long kvmppc_get_guest_page(struct kvm *kvm, unsigned long gfn, | ||
267 | struct kvm_memory_slot *memslot, | ||
268 | unsigned long psize) | ||
269 | { | ||
270 | unsigned long start; | ||
271 | long np, err; | ||
272 | struct page *page, *hpage, *pages[1]; | ||
273 | unsigned long s, pgsize; | ||
274 | unsigned long *physp; | ||
275 | unsigned int is_io, got, pgorder; | ||
276 | struct vm_area_struct *vma; | ||
277 | unsigned long pfn, i, npages; | ||
278 | |||
279 | physp = memslot->arch.slot_phys; | ||
280 | if (!physp) | ||
281 | return -EINVAL; | ||
282 | if (physp[gfn - memslot->base_gfn]) | ||
283 | return 0; | ||
284 | |||
285 | is_io = 0; | ||
286 | got = 0; | ||
287 | page = NULL; | ||
288 | pgsize = psize; | ||
289 | err = -EINVAL; | ||
290 | start = gfn_to_hva_memslot(memslot, gfn); | ||
291 | |||
292 | /* Instantiate and get the page we want access to */ | ||
293 | np = get_user_pages_fast(start, 1, 1, pages); | ||
294 | if (np != 1) { | ||
295 | /* Look up the vma for the page */ | ||
296 | down_read(¤t->mm->mmap_sem); | ||
297 | vma = find_vma(current->mm, start); | ||
298 | if (!vma || vma->vm_start > start || | ||
299 | start + psize > vma->vm_end || | ||
300 | !(vma->vm_flags & VM_PFNMAP)) | ||
301 | goto up_err; | ||
302 | is_io = hpte_cache_bits(pgprot_val(vma->vm_page_prot)); | ||
303 | pfn = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT); | ||
304 | /* check alignment of pfn vs. requested page size */ | ||
305 | if (psize > PAGE_SIZE && (pfn & ((psize >> PAGE_SHIFT) - 1))) | ||
306 | goto up_err; | ||
307 | up_read(¤t->mm->mmap_sem); | ||
308 | |||
309 | } else { | ||
310 | page = pages[0]; | ||
311 | got = KVMPPC_GOT_PAGE; | ||
312 | |||
313 | /* See if this is a large page */ | ||
314 | s = PAGE_SIZE; | ||
315 | if (PageHuge(page)) { | ||
316 | hpage = compound_head(page); | ||
317 | s <<= compound_order(hpage); | ||
318 | /* Get the whole large page if slot alignment is ok */ | ||
319 | if (s > psize && slot_is_aligned(memslot, s) && | ||
320 | !(memslot->userspace_addr & (s - 1))) { | ||
321 | start &= ~(s - 1); | ||
322 | pgsize = s; | ||
323 | get_page(hpage); | ||
324 | put_page(page); | ||
325 | page = hpage; | ||
326 | } | ||
327 | } | ||
328 | if (s < psize) | ||
329 | goto out; | ||
330 | pfn = page_to_pfn(page); | ||
331 | } | ||
332 | |||
333 | npages = pgsize >> PAGE_SHIFT; | ||
334 | pgorder = __ilog2(npages); | ||
335 | physp += (gfn - memslot->base_gfn) & ~(npages - 1); | ||
336 | spin_lock(&kvm->arch.slot_phys_lock); | ||
337 | for (i = 0; i < npages; ++i) { | ||
338 | if (!physp[i]) { | ||
339 | physp[i] = ((pfn + i) << PAGE_SHIFT) + | ||
340 | got + is_io + pgorder; | ||
341 | got = 0; | ||
342 | } | ||
343 | } | ||
344 | spin_unlock(&kvm->arch.slot_phys_lock); | ||
345 | err = 0; | ||
346 | |||
347 | out: | ||
348 | if (got) | ||
349 | put_page(page); | ||
350 | return err; | ||
351 | |||
352 | up_err: | ||
353 | up_read(¤t->mm->mmap_sem); | ||
354 | return err; | ||
355 | } | ||
356 | |||
357 | long kvmppc_virtmode_do_h_enter(struct kvm *kvm, unsigned long flags, | 256 | long kvmppc_virtmode_do_h_enter(struct kvm *kvm, unsigned long flags, |
358 | long pte_index, unsigned long pteh, | 257 | long pte_index, unsigned long pteh, |
359 | unsigned long ptel, unsigned long *pte_idx_ret) | 258 | unsigned long ptel, unsigned long *pte_idx_ret) |
360 | { | 259 | { |
361 | unsigned long psize, gpa, gfn; | ||
362 | struct kvm_memory_slot *memslot; | ||
363 | long ret; | 260 | long ret; |
364 | 261 | ||
365 | if (kvm->arch.using_mmu_notifiers) | ||
366 | goto do_insert; | ||
367 | |||
368 | psize = hpte_page_size(pteh, ptel); | ||
369 | if (!psize) | ||
370 | return H_PARAMETER; | ||
371 | |||
372 | pteh &= ~(HPTE_V_HVLOCK | HPTE_V_ABSENT | HPTE_V_VALID); | ||
373 | |||
374 | /* Find the memslot (if any) for this address */ | ||
375 | gpa = (ptel & HPTE_R_RPN) & ~(psize - 1); | ||
376 | gfn = gpa >> PAGE_SHIFT; | ||
377 | memslot = gfn_to_memslot(kvm, gfn); | ||
378 | if (memslot && !(memslot->flags & KVM_MEMSLOT_INVALID)) { | ||
379 | if (!slot_is_aligned(memslot, psize)) | ||
380 | return H_PARAMETER; | ||
381 | if (kvmppc_get_guest_page(kvm, gfn, memslot, psize) < 0) | ||
382 | return H_PARAMETER; | ||
383 | } | ||
384 | |||
385 | do_insert: | ||
386 | /* Protect linux PTE lookup from page table destruction */ | 262 | /* Protect linux PTE lookup from page table destruction */ |
387 | rcu_read_lock_sched(); /* this disables preemption too */ | 263 | rcu_read_lock_sched(); /* this disables preemption too */ |
388 | ret = kvmppc_do_h_enter(kvm, flags, pte_index, pteh, ptel, | 264 | ret = kvmppc_do_h_enter(kvm, flags, pte_index, pteh, ptel, |
@@ -397,19 +273,6 @@ long kvmppc_virtmode_do_h_enter(struct kvm *kvm, unsigned long flags, | |||
397 | 273 | ||
398 | } | 274 | } |
399 | 275 | ||
400 | /* | ||
401 | * We come here on a H_ENTER call from the guest when we are not | ||
402 | * using mmu notifiers and we don't have the requested page pinned | ||
403 | * already. | ||
404 | */ | ||
405 | long kvmppc_virtmode_h_enter(struct kvm_vcpu *vcpu, unsigned long flags, | ||
406 | long pte_index, unsigned long pteh, | ||
407 | unsigned long ptel) | ||
408 | { | ||
409 | return kvmppc_virtmode_do_h_enter(vcpu->kvm, flags, pte_index, | ||
410 | pteh, ptel, &vcpu->arch.gpr[4]); | ||
411 | } | ||
412 | |||
413 | static struct kvmppc_slb *kvmppc_mmu_book3s_hv_find_slbe(struct kvm_vcpu *vcpu, | 276 | static struct kvmppc_slb *kvmppc_mmu_book3s_hv_find_slbe(struct kvm_vcpu *vcpu, |
414 | gva_t eaddr) | 277 | gva_t eaddr) |
415 | { | 278 | { |
@@ -494,7 +357,7 @@ static int kvmppc_mmu_book3s_64_hv_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, | |||
494 | gpte->may_execute = gpte->may_read && !(gr & (HPTE_R_N | HPTE_R_G)); | 357 | gpte->may_execute = gpte->may_read && !(gr & (HPTE_R_N | HPTE_R_G)); |
495 | 358 | ||
496 | /* Storage key permission check for POWER7 */ | 359 | /* Storage key permission check for POWER7 */ |
497 | if (data && virtmode && cpu_has_feature(CPU_FTR_ARCH_206)) { | 360 | if (data && virtmode) { |
498 | int amrfield = hpte_get_skey_perm(gr, vcpu->arch.amr); | 361 | int amrfield = hpte_get_skey_perm(gr, vcpu->arch.amr); |
499 | if (amrfield & 1) | 362 | if (amrfield & 1) |
500 | gpte->may_read = 0; | 363 | gpte->may_read = 0; |
@@ -622,14 +485,13 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
622 | gfn = gpa >> PAGE_SHIFT; | 485 | gfn = gpa >> PAGE_SHIFT; |
623 | memslot = gfn_to_memslot(kvm, gfn); | 486 | memslot = gfn_to_memslot(kvm, gfn); |
624 | 487 | ||
488 | trace_kvm_page_fault_enter(vcpu, hpte, memslot, ea, dsisr); | ||
489 | |||
625 | /* No memslot means it's an emulated MMIO region */ | 490 | /* No memslot means it's an emulated MMIO region */ |
626 | if (!memslot || (memslot->flags & KVM_MEMSLOT_INVALID)) | 491 | if (!memslot || (memslot->flags & KVM_MEMSLOT_INVALID)) |
627 | return kvmppc_hv_emulate_mmio(run, vcpu, gpa, ea, | 492 | return kvmppc_hv_emulate_mmio(run, vcpu, gpa, ea, |
628 | dsisr & DSISR_ISSTORE); | 493 | dsisr & DSISR_ISSTORE); |
629 | 494 | ||
630 | if (!kvm->arch.using_mmu_notifiers) | ||
631 | return -EFAULT; /* should never get here */ | ||
632 | |||
633 | /* | 495 | /* |
634 | * This should never happen, because of the slot_is_aligned() | 496 | * This should never happen, because of the slot_is_aligned() |
635 | * check in kvmppc_do_h_enter(). | 497 | * check in kvmppc_do_h_enter(). |
@@ -641,6 +503,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
641 | mmu_seq = kvm->mmu_notifier_seq; | 503 | mmu_seq = kvm->mmu_notifier_seq; |
642 | smp_rmb(); | 504 | smp_rmb(); |
643 | 505 | ||
506 | ret = -EFAULT; | ||
644 | is_io = 0; | 507 | is_io = 0; |
645 | pfn = 0; | 508 | pfn = 0; |
646 | page = NULL; | 509 | page = NULL; |
@@ -664,7 +527,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
664 | } | 527 | } |
665 | up_read(¤t->mm->mmap_sem); | 528 | up_read(¤t->mm->mmap_sem); |
666 | if (!pfn) | 529 | if (!pfn) |
667 | return -EFAULT; | 530 | goto out_put; |
668 | } else { | 531 | } else { |
669 | page = pages[0]; | 532 | page = pages[0]; |
670 | pfn = page_to_pfn(page); | 533 | pfn = page_to_pfn(page); |
@@ -694,14 +557,14 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
694 | } | 557 | } |
695 | } | 558 | } |
696 | 559 | ||
697 | ret = -EFAULT; | ||
698 | if (psize > pte_size) | 560 | if (psize > pte_size) |
699 | goto out_put; | 561 | goto out_put; |
700 | 562 | ||
701 | /* Check WIMG vs. the actual page we're accessing */ | 563 | /* Check WIMG vs. the actual page we're accessing */ |
702 | if (!hpte_cache_flags_ok(r, is_io)) { | 564 | if (!hpte_cache_flags_ok(r, is_io)) { |
703 | if (is_io) | 565 | if (is_io) |
704 | return -EFAULT; | 566 | goto out_put; |
567 | |||
705 | /* | 568 | /* |
706 | * Allow guest to map emulated device memory as | 569 | * Allow guest to map emulated device memory as |
707 | * uncacheable, but actually make it cacheable. | 570 | * uncacheable, but actually make it cacheable. |
@@ -765,6 +628,8 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
765 | SetPageDirty(page); | 628 | SetPageDirty(page); |
766 | 629 | ||
767 | out_put: | 630 | out_put: |
631 | trace_kvm_page_fault_exit(vcpu, hpte, ret); | ||
632 | |||
768 | if (page) { | 633 | if (page) { |
769 | /* | 634 | /* |
770 | * We drop pages[0] here, not page because page might | 635 | * We drop pages[0] here, not page because page might |
@@ -895,8 +760,7 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
895 | psize = hpte_page_size(be64_to_cpu(hptep[0]), ptel); | 760 | psize = hpte_page_size(be64_to_cpu(hptep[0]), ptel); |
896 | if ((be64_to_cpu(hptep[0]) & HPTE_V_VALID) && | 761 | if ((be64_to_cpu(hptep[0]) & HPTE_V_VALID) && |
897 | hpte_rpn(ptel, psize) == gfn) { | 762 | hpte_rpn(ptel, psize) == gfn) { |
898 | if (kvm->arch.using_mmu_notifiers) | 763 | hptep[0] |= cpu_to_be64(HPTE_V_ABSENT); |
899 | hptep[0] |= cpu_to_be64(HPTE_V_ABSENT); | ||
900 | kvmppc_invalidate_hpte(kvm, hptep, i); | 764 | kvmppc_invalidate_hpte(kvm, hptep, i); |
901 | /* Harvest R and C */ | 765 | /* Harvest R and C */ |
902 | rcbits = be64_to_cpu(hptep[1]) & (HPTE_R_R | HPTE_R_C); | 766 | rcbits = be64_to_cpu(hptep[1]) & (HPTE_R_R | HPTE_R_C); |
@@ -914,15 +778,13 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
914 | 778 | ||
915 | int kvm_unmap_hva_hv(struct kvm *kvm, unsigned long hva) | 779 | int kvm_unmap_hva_hv(struct kvm *kvm, unsigned long hva) |
916 | { | 780 | { |
917 | if (kvm->arch.using_mmu_notifiers) | 781 | kvm_handle_hva(kvm, hva, kvm_unmap_rmapp); |
918 | kvm_handle_hva(kvm, hva, kvm_unmap_rmapp); | ||
919 | return 0; | 782 | return 0; |
920 | } | 783 | } |
921 | 784 | ||
922 | int kvm_unmap_hva_range_hv(struct kvm *kvm, unsigned long start, unsigned long end) | 785 | int kvm_unmap_hva_range_hv(struct kvm *kvm, unsigned long start, unsigned long end) |
923 | { | 786 | { |
924 | if (kvm->arch.using_mmu_notifiers) | 787 | kvm_handle_hva_range(kvm, start, end, kvm_unmap_rmapp); |
925 | kvm_handle_hva_range(kvm, start, end, kvm_unmap_rmapp); | ||
926 | return 0; | 788 | return 0; |
927 | } | 789 | } |
928 | 790 | ||
@@ -1004,8 +866,6 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
1004 | 866 | ||
1005 | int kvm_age_hva_hv(struct kvm *kvm, unsigned long start, unsigned long end) | 867 | int kvm_age_hva_hv(struct kvm *kvm, unsigned long start, unsigned long end) |
1006 | { | 868 | { |
1007 | if (!kvm->arch.using_mmu_notifiers) | ||
1008 | return 0; | ||
1009 | return kvm_handle_hva_range(kvm, start, end, kvm_age_rmapp); | 869 | return kvm_handle_hva_range(kvm, start, end, kvm_age_rmapp); |
1010 | } | 870 | } |
1011 | 871 | ||
@@ -1042,15 +902,11 @@ static int kvm_test_age_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
1042 | 902 | ||
1043 | int kvm_test_age_hva_hv(struct kvm *kvm, unsigned long hva) | 903 | int kvm_test_age_hva_hv(struct kvm *kvm, unsigned long hva) |
1044 | { | 904 | { |
1045 | if (!kvm->arch.using_mmu_notifiers) | ||
1046 | return 0; | ||
1047 | return kvm_handle_hva(kvm, hva, kvm_test_age_rmapp); | 905 | return kvm_handle_hva(kvm, hva, kvm_test_age_rmapp); |
1048 | } | 906 | } |
1049 | 907 | ||
1050 | void kvm_set_spte_hva_hv(struct kvm *kvm, unsigned long hva, pte_t pte) | 908 | void kvm_set_spte_hva_hv(struct kvm *kvm, unsigned long hva, pte_t pte) |
1051 | { | 909 | { |
1052 | if (!kvm->arch.using_mmu_notifiers) | ||
1053 | return; | ||
1054 | kvm_handle_hva(kvm, hva, kvm_unmap_rmapp); | 910 | kvm_handle_hva(kvm, hva, kvm_unmap_rmapp); |
1055 | } | 911 | } |
1056 | 912 | ||
@@ -1117,8 +973,11 @@ static int kvm_test_clear_dirty_npages(struct kvm *kvm, unsigned long *rmapp) | |||
1117 | } | 973 | } |
1118 | 974 | ||
1119 | /* Now check and modify the HPTE */ | 975 | /* Now check and modify the HPTE */ |
1120 | if (!(hptep[0] & cpu_to_be64(HPTE_V_VALID))) | 976 | if (!(hptep[0] & cpu_to_be64(HPTE_V_VALID))) { |
977 | /* unlock and continue */ | ||
978 | hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK); | ||
1121 | continue; | 979 | continue; |
980 | } | ||
1122 | 981 | ||
1123 | /* need to make it temporarily absent so C is stable */ | 982 | /* need to make it temporarily absent so C is stable */ |
1124 | hptep[0] |= cpu_to_be64(HPTE_V_ABSENT); | 983 | hptep[0] |= cpu_to_be64(HPTE_V_ABSENT); |
@@ -1206,35 +1065,17 @@ void *kvmppc_pin_guest_page(struct kvm *kvm, unsigned long gpa, | |||
1206 | struct page *page, *pages[1]; | 1065 | struct page *page, *pages[1]; |
1207 | int npages; | 1066 | int npages; |
1208 | unsigned long hva, offset; | 1067 | unsigned long hva, offset; |
1209 | unsigned long pa; | ||
1210 | unsigned long *physp; | ||
1211 | int srcu_idx; | 1068 | int srcu_idx; |
1212 | 1069 | ||
1213 | srcu_idx = srcu_read_lock(&kvm->srcu); | 1070 | srcu_idx = srcu_read_lock(&kvm->srcu); |
1214 | memslot = gfn_to_memslot(kvm, gfn); | 1071 | memslot = gfn_to_memslot(kvm, gfn); |
1215 | if (!memslot || (memslot->flags & KVM_MEMSLOT_INVALID)) | 1072 | if (!memslot || (memslot->flags & KVM_MEMSLOT_INVALID)) |
1216 | goto err; | 1073 | goto err; |
1217 | if (!kvm->arch.using_mmu_notifiers) { | 1074 | hva = gfn_to_hva_memslot(memslot, gfn); |
1218 | physp = memslot->arch.slot_phys; | 1075 | npages = get_user_pages_fast(hva, 1, 1, pages); |
1219 | if (!physp) | 1076 | if (npages < 1) |
1220 | goto err; | 1077 | goto err; |
1221 | physp += gfn - memslot->base_gfn; | 1078 | page = pages[0]; |
1222 | pa = *physp; | ||
1223 | if (!pa) { | ||
1224 | if (kvmppc_get_guest_page(kvm, gfn, memslot, | ||
1225 | PAGE_SIZE) < 0) | ||
1226 | goto err; | ||
1227 | pa = *physp; | ||
1228 | } | ||
1229 | page = pfn_to_page(pa >> PAGE_SHIFT); | ||
1230 | get_page(page); | ||
1231 | } else { | ||
1232 | hva = gfn_to_hva_memslot(memslot, gfn); | ||
1233 | npages = get_user_pages_fast(hva, 1, 1, pages); | ||
1234 | if (npages < 1) | ||
1235 | goto err; | ||
1236 | page = pages[0]; | ||
1237 | } | ||
1238 | srcu_read_unlock(&kvm->srcu, srcu_idx); | 1079 | srcu_read_unlock(&kvm->srcu, srcu_idx); |
1239 | 1080 | ||
1240 | offset = gpa & (PAGE_SIZE - 1); | 1081 | offset = gpa & (PAGE_SIZE - 1); |
@@ -1258,7 +1099,7 @@ void kvmppc_unpin_guest_page(struct kvm *kvm, void *va, unsigned long gpa, | |||
1258 | 1099 | ||
1259 | put_page(page); | 1100 | put_page(page); |
1260 | 1101 | ||
1261 | if (!dirty || !kvm->arch.using_mmu_notifiers) | 1102 | if (!dirty) |
1262 | return; | 1103 | return; |
1263 | 1104 | ||
1264 | /* We need to mark this page dirty in the rmap chain */ | 1105 | /* We need to mark this page dirty in the rmap chain */ |
@@ -1539,9 +1380,15 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf, | |||
1539 | hptp = (__be64 *)(kvm->arch.hpt_virt + (i * HPTE_SIZE)); | 1380 | hptp = (__be64 *)(kvm->arch.hpt_virt + (i * HPTE_SIZE)); |
1540 | lbuf = (unsigned long __user *)buf; | 1381 | lbuf = (unsigned long __user *)buf; |
1541 | for (j = 0; j < hdr.n_valid; ++j) { | 1382 | for (j = 0; j < hdr.n_valid; ++j) { |
1383 | __be64 hpte_v; | ||
1384 | __be64 hpte_r; | ||
1385 | |||
1542 | err = -EFAULT; | 1386 | err = -EFAULT; |
1543 | if (__get_user(v, lbuf) || __get_user(r, lbuf + 1)) | 1387 | if (__get_user(hpte_v, lbuf) || |
1388 | __get_user(hpte_r, lbuf + 1)) | ||
1544 | goto out; | 1389 | goto out; |
1390 | v = be64_to_cpu(hpte_v); | ||
1391 | r = be64_to_cpu(hpte_r); | ||
1545 | err = -EINVAL; | 1392 | err = -EINVAL; |
1546 | if (!(v & HPTE_V_VALID)) | 1393 | if (!(v & HPTE_V_VALID)) |
1547 | goto out; | 1394 | goto out; |
@@ -1652,10 +1499,7 @@ void kvmppc_mmu_book3s_hv_init(struct kvm_vcpu *vcpu) | |||
1652 | { | 1499 | { |
1653 | struct kvmppc_mmu *mmu = &vcpu->arch.mmu; | 1500 | struct kvmppc_mmu *mmu = &vcpu->arch.mmu; |
1654 | 1501 | ||
1655 | if (cpu_has_feature(CPU_FTR_ARCH_206)) | 1502 | vcpu->arch.slb_nr = 32; /* POWER7/POWER8 */ |
1656 | vcpu->arch.slb_nr = 32; /* POWER7 */ | ||
1657 | else | ||
1658 | vcpu->arch.slb_nr = 64; | ||
1659 | 1503 | ||
1660 | mmu->xlate = kvmppc_mmu_book3s_64_hv_xlate; | 1504 | mmu->xlate = kvmppc_mmu_book3s_64_hv_xlate; |
1661 | mmu->reset_msr = kvmppc_mmu_book3s_64_hv_reset_msr; | 1505 | mmu->reset_msr = kvmppc_mmu_book3s_64_hv_reset_msr; |
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index e63587d30b70..de4018a1bc4b 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c | |||
@@ -58,6 +58,9 @@ | |||
58 | 58 | ||
59 | #include "book3s.h" | 59 | #include "book3s.h" |
60 | 60 | ||
61 | #define CREATE_TRACE_POINTS | ||
62 | #include "trace_hv.h" | ||
63 | |||
61 | /* #define EXIT_DEBUG */ | 64 | /* #define EXIT_DEBUG */ |
62 | /* #define EXIT_DEBUG_SIMPLE */ | 65 | /* #define EXIT_DEBUG_SIMPLE */ |
63 | /* #define EXIT_DEBUG_INT */ | 66 | /* #define EXIT_DEBUG_INT */ |
@@ -135,11 +138,10 @@ static void kvmppc_fast_vcpu_kick_hv(struct kvm_vcpu *vcpu) | |||
135 | * stolen. | 138 | * stolen. |
136 | * | 139 | * |
137 | * Updates to busy_stolen are protected by arch.tbacct_lock; | 140 | * Updates to busy_stolen are protected by arch.tbacct_lock; |
138 | * updates to vc->stolen_tb are protected by the arch.tbacct_lock | 141 | * updates to vc->stolen_tb are protected by the vcore->stoltb_lock |
139 | * of the vcpu that has taken responsibility for running the vcore | 142 | * lock. The stolen times are measured in units of timebase ticks. |
140 | * (i.e. vc->runner). The stolen times are measured in units of | 143 | * (Note that the != TB_NIL checks below are purely defensive; |
141 | * timebase ticks. (Note that the != TB_NIL checks below are | 144 | * they should never fail.) |
142 | * purely defensive; they should never fail.) | ||
143 | */ | 145 | */ |
144 | 146 | ||
145 | static void kvmppc_core_vcpu_load_hv(struct kvm_vcpu *vcpu, int cpu) | 147 | static void kvmppc_core_vcpu_load_hv(struct kvm_vcpu *vcpu, int cpu) |
@@ -147,12 +149,21 @@ static void kvmppc_core_vcpu_load_hv(struct kvm_vcpu *vcpu, int cpu) | |||
147 | struct kvmppc_vcore *vc = vcpu->arch.vcore; | 149 | struct kvmppc_vcore *vc = vcpu->arch.vcore; |
148 | unsigned long flags; | 150 | unsigned long flags; |
149 | 151 | ||
150 | spin_lock_irqsave(&vcpu->arch.tbacct_lock, flags); | 152 | /* |
151 | if (vc->runner == vcpu && vc->vcore_state != VCORE_INACTIVE && | 153 | * We can test vc->runner without taking the vcore lock, |
152 | vc->preempt_tb != TB_NIL) { | 154 | * because only this task ever sets vc->runner to this |
153 | vc->stolen_tb += mftb() - vc->preempt_tb; | 155 | * vcpu, and once it is set to this vcpu, only this task |
154 | vc->preempt_tb = TB_NIL; | 156 | * ever sets it to NULL. |
157 | */ | ||
158 | if (vc->runner == vcpu && vc->vcore_state != VCORE_INACTIVE) { | ||
159 | spin_lock_irqsave(&vc->stoltb_lock, flags); | ||
160 | if (vc->preempt_tb != TB_NIL) { | ||
161 | vc->stolen_tb += mftb() - vc->preempt_tb; | ||
162 | vc->preempt_tb = TB_NIL; | ||
163 | } | ||
164 | spin_unlock_irqrestore(&vc->stoltb_lock, flags); | ||
155 | } | 165 | } |
166 | spin_lock_irqsave(&vcpu->arch.tbacct_lock, flags); | ||
156 | if (vcpu->arch.state == KVMPPC_VCPU_BUSY_IN_HOST && | 167 | if (vcpu->arch.state == KVMPPC_VCPU_BUSY_IN_HOST && |
157 | vcpu->arch.busy_preempt != TB_NIL) { | 168 | vcpu->arch.busy_preempt != TB_NIL) { |
158 | vcpu->arch.busy_stolen += mftb() - vcpu->arch.busy_preempt; | 169 | vcpu->arch.busy_stolen += mftb() - vcpu->arch.busy_preempt; |
@@ -166,9 +177,12 @@ static void kvmppc_core_vcpu_put_hv(struct kvm_vcpu *vcpu) | |||
166 | struct kvmppc_vcore *vc = vcpu->arch.vcore; | 177 | struct kvmppc_vcore *vc = vcpu->arch.vcore; |
167 | unsigned long flags; | 178 | unsigned long flags; |
168 | 179 | ||
169 | spin_lock_irqsave(&vcpu->arch.tbacct_lock, flags); | 180 | if (vc->runner == vcpu && vc->vcore_state != VCORE_INACTIVE) { |
170 | if (vc->runner == vcpu && vc->vcore_state != VCORE_INACTIVE) | 181 | spin_lock_irqsave(&vc->stoltb_lock, flags); |
171 | vc->preempt_tb = mftb(); | 182 | vc->preempt_tb = mftb(); |
183 | spin_unlock_irqrestore(&vc->stoltb_lock, flags); | ||
184 | } | ||
185 | spin_lock_irqsave(&vcpu->arch.tbacct_lock, flags); | ||
172 | if (vcpu->arch.state == KVMPPC_VCPU_BUSY_IN_HOST) | 186 | if (vcpu->arch.state == KVMPPC_VCPU_BUSY_IN_HOST) |
173 | vcpu->arch.busy_preempt = mftb(); | 187 | vcpu->arch.busy_preempt = mftb(); |
174 | spin_unlock_irqrestore(&vcpu->arch.tbacct_lock, flags); | 188 | spin_unlock_irqrestore(&vcpu->arch.tbacct_lock, flags); |
@@ -191,9 +205,6 @@ int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat) | |||
191 | struct kvmppc_vcore *vc = vcpu->arch.vcore; | 205 | struct kvmppc_vcore *vc = vcpu->arch.vcore; |
192 | 206 | ||
193 | if (arch_compat) { | 207 | if (arch_compat) { |
194 | if (!cpu_has_feature(CPU_FTR_ARCH_206)) | ||
195 | return -EINVAL; /* 970 has no compat mode support */ | ||
196 | |||
197 | switch (arch_compat) { | 208 | switch (arch_compat) { |
198 | case PVR_ARCH_205: | 209 | case PVR_ARCH_205: |
199 | /* | 210 | /* |
@@ -505,25 +516,14 @@ static void kvmppc_update_vpas(struct kvm_vcpu *vcpu) | |||
505 | static u64 vcore_stolen_time(struct kvmppc_vcore *vc, u64 now) | 516 | static u64 vcore_stolen_time(struct kvmppc_vcore *vc, u64 now) |
506 | { | 517 | { |
507 | u64 p; | 518 | u64 p; |
519 | unsigned long flags; | ||
508 | 520 | ||
509 | /* | 521 | spin_lock_irqsave(&vc->stoltb_lock, flags); |
510 | * If we are the task running the vcore, then since we hold | 522 | p = vc->stolen_tb; |
511 | * the vcore lock, we can't be preempted, so stolen_tb/preempt_tb | ||
512 | * can't be updated, so we don't need the tbacct_lock. | ||
513 | * If the vcore is inactive, it can't become active (since we | ||
514 | * hold the vcore lock), so the vcpu load/put functions won't | ||
515 | * update stolen_tb/preempt_tb, and we don't need tbacct_lock. | ||
516 | */ | ||
517 | if (vc->vcore_state != VCORE_INACTIVE && | 523 | if (vc->vcore_state != VCORE_INACTIVE && |
518 | vc->runner->arch.run_task != current) { | 524 | vc->preempt_tb != TB_NIL) |
519 | spin_lock_irq(&vc->runner->arch.tbacct_lock); | 525 | p += now - vc->preempt_tb; |
520 | p = vc->stolen_tb; | 526 | spin_unlock_irqrestore(&vc->stoltb_lock, flags); |
521 | if (vc->preempt_tb != TB_NIL) | ||
522 | p += now - vc->preempt_tb; | ||
523 | spin_unlock_irq(&vc->runner->arch.tbacct_lock); | ||
524 | } else { | ||
525 | p = vc->stolen_tb; | ||
526 | } | ||
527 | return p; | 527 | return p; |
528 | } | 528 | } |
529 | 529 | ||
@@ -607,10 +607,45 @@ static int kvmppc_h_set_mode(struct kvm_vcpu *vcpu, unsigned long mflags, | |||
607 | } | 607 | } |
608 | } | 608 | } |
609 | 609 | ||
610 | static int kvm_arch_vcpu_yield_to(struct kvm_vcpu *target) | ||
611 | { | ||
612 | struct kvmppc_vcore *vcore = target->arch.vcore; | ||
613 | |||
614 | /* | ||
615 | * We expect to have been called by the real mode handler | ||
616 | * (kvmppc_rm_h_confer()) which would have directly returned | ||
617 | * H_SUCCESS if the source vcore wasn't idle (e.g. if it may | ||
618 | * have useful work to do and should not confer) so we don't | ||
619 | * recheck that here. | ||
620 | */ | ||
621 | |||
622 | spin_lock(&vcore->lock); | ||
623 | if (target->arch.state == KVMPPC_VCPU_RUNNABLE && | ||
624 | vcore->vcore_state != VCORE_INACTIVE) | ||
625 | target = vcore->runner; | ||
626 | spin_unlock(&vcore->lock); | ||
627 | |||
628 | return kvm_vcpu_yield_to(target); | ||
629 | } | ||
630 | |||
631 | static int kvmppc_get_yield_count(struct kvm_vcpu *vcpu) | ||
632 | { | ||
633 | int yield_count = 0; | ||
634 | struct lppaca *lppaca; | ||
635 | |||
636 | spin_lock(&vcpu->arch.vpa_update_lock); | ||
637 | lppaca = (struct lppaca *)vcpu->arch.vpa.pinned_addr; | ||
638 | if (lppaca) | ||
639 | yield_count = lppaca->yield_count; | ||
640 | spin_unlock(&vcpu->arch.vpa_update_lock); | ||
641 | return yield_count; | ||
642 | } | ||
643 | |||
610 | int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) | 644 | int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) |
611 | { | 645 | { |
612 | unsigned long req = kvmppc_get_gpr(vcpu, 3); | 646 | unsigned long req = kvmppc_get_gpr(vcpu, 3); |
613 | unsigned long target, ret = H_SUCCESS; | 647 | unsigned long target, ret = H_SUCCESS; |
648 | int yield_count; | ||
614 | struct kvm_vcpu *tvcpu; | 649 | struct kvm_vcpu *tvcpu; |
615 | int idx, rc; | 650 | int idx, rc; |
616 | 651 | ||
@@ -619,14 +654,6 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) | |||
619 | return RESUME_HOST; | 654 | return RESUME_HOST; |
620 | 655 | ||
621 | switch (req) { | 656 | switch (req) { |
622 | case H_ENTER: | ||
623 | idx = srcu_read_lock(&vcpu->kvm->srcu); | ||
624 | ret = kvmppc_virtmode_h_enter(vcpu, kvmppc_get_gpr(vcpu, 4), | ||
625 | kvmppc_get_gpr(vcpu, 5), | ||
626 | kvmppc_get_gpr(vcpu, 6), | ||
627 | kvmppc_get_gpr(vcpu, 7)); | ||
628 | srcu_read_unlock(&vcpu->kvm->srcu, idx); | ||
629 | break; | ||
630 | case H_CEDE: | 657 | case H_CEDE: |
631 | break; | 658 | break; |
632 | case H_PROD: | 659 | case H_PROD: |
@@ -654,7 +681,10 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) | |||
654 | ret = H_PARAMETER; | 681 | ret = H_PARAMETER; |
655 | break; | 682 | break; |
656 | } | 683 | } |
657 | kvm_vcpu_yield_to(tvcpu); | 684 | yield_count = kvmppc_get_gpr(vcpu, 5); |
685 | if (kvmppc_get_yield_count(tvcpu) != yield_count) | ||
686 | break; | ||
687 | kvm_arch_vcpu_yield_to(tvcpu); | ||
658 | break; | 688 | break; |
659 | case H_REGISTER_VPA: | 689 | case H_REGISTER_VPA: |
660 | ret = do_h_register_vpa(vcpu, kvmppc_get_gpr(vcpu, 4), | 690 | ret = do_h_register_vpa(vcpu, kvmppc_get_gpr(vcpu, 4), |
@@ -769,6 +799,8 @@ static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
769 | vcpu->stat.ext_intr_exits++; | 799 | vcpu->stat.ext_intr_exits++; |
770 | r = RESUME_GUEST; | 800 | r = RESUME_GUEST; |
771 | break; | 801 | break; |
802 | /* HMI is hypervisor interrupt and host has handled it. Resume guest.*/ | ||
803 | case BOOK3S_INTERRUPT_HMI: | ||
772 | case BOOK3S_INTERRUPT_PERFMON: | 804 | case BOOK3S_INTERRUPT_PERFMON: |
773 | r = RESUME_GUEST; | 805 | r = RESUME_GUEST; |
774 | break; | 806 | break; |
@@ -837,6 +869,10 @@ static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
837 | * Accordingly return to Guest or Host. | 869 | * Accordingly return to Guest or Host. |
838 | */ | 870 | */ |
839 | case BOOK3S_INTERRUPT_H_EMUL_ASSIST: | 871 | case BOOK3S_INTERRUPT_H_EMUL_ASSIST: |
872 | if (vcpu->arch.emul_inst != KVM_INST_FETCH_FAILED) | ||
873 | vcpu->arch.last_inst = kvmppc_need_byteswap(vcpu) ? | ||
874 | swab32(vcpu->arch.emul_inst) : | ||
875 | vcpu->arch.emul_inst; | ||
840 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP) { | 876 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP) { |
841 | r = kvmppc_emulate_debug_inst(run, vcpu); | 877 | r = kvmppc_emulate_debug_inst(run, vcpu); |
842 | } else { | 878 | } else { |
@@ -1357,6 +1393,7 @@ static struct kvmppc_vcore *kvmppc_vcore_create(struct kvm *kvm, int core) | |||
1357 | 1393 | ||
1358 | INIT_LIST_HEAD(&vcore->runnable_threads); | 1394 | INIT_LIST_HEAD(&vcore->runnable_threads); |
1359 | spin_lock_init(&vcore->lock); | 1395 | spin_lock_init(&vcore->lock); |
1396 | spin_lock_init(&vcore->stoltb_lock); | ||
1360 | init_waitqueue_head(&vcore->wq); | 1397 | init_waitqueue_head(&vcore->wq); |
1361 | vcore->preempt_tb = TB_NIL; | 1398 | vcore->preempt_tb = TB_NIL; |
1362 | vcore->lpcr = kvm->arch.lpcr; | 1399 | vcore->lpcr = kvm->arch.lpcr; |
@@ -1694,9 +1731,11 @@ static void kvmppc_run_core(struct kvmppc_vcore *vc) | |||
1694 | vc->n_woken = 0; | 1731 | vc->n_woken = 0; |
1695 | vc->nap_count = 0; | 1732 | vc->nap_count = 0; |
1696 | vc->entry_exit_count = 0; | 1733 | vc->entry_exit_count = 0; |
1734 | vc->preempt_tb = TB_NIL; | ||
1697 | vc->vcore_state = VCORE_STARTING; | 1735 | vc->vcore_state = VCORE_STARTING; |
1698 | vc->in_guest = 0; | 1736 | vc->in_guest = 0; |
1699 | vc->napping_threads = 0; | 1737 | vc->napping_threads = 0; |
1738 | vc->conferring_threads = 0; | ||
1700 | 1739 | ||
1701 | /* | 1740 | /* |
1702 | * Updating any of the vpas requires calling kvmppc_pin_guest_page, | 1741 | * Updating any of the vpas requires calling kvmppc_pin_guest_page, |
@@ -1726,6 +1765,7 @@ static void kvmppc_run_core(struct kvmppc_vcore *vc) | |||
1726 | list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) { | 1765 | list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) { |
1727 | kvmppc_start_thread(vcpu); | 1766 | kvmppc_start_thread(vcpu); |
1728 | kvmppc_create_dtl_entry(vcpu, vc); | 1767 | kvmppc_create_dtl_entry(vcpu, vc); |
1768 | trace_kvm_guest_enter(vcpu); | ||
1729 | } | 1769 | } |
1730 | 1770 | ||
1731 | /* Set this explicitly in case thread 0 doesn't have a vcpu */ | 1771 | /* Set this explicitly in case thread 0 doesn't have a vcpu */ |
@@ -1734,6 +1774,9 @@ static void kvmppc_run_core(struct kvmppc_vcore *vc) | |||
1734 | 1774 | ||
1735 | vc->vcore_state = VCORE_RUNNING; | 1775 | vc->vcore_state = VCORE_RUNNING; |
1736 | preempt_disable(); | 1776 | preempt_disable(); |
1777 | |||
1778 | trace_kvmppc_run_core(vc, 0); | ||
1779 | |||
1737 | spin_unlock(&vc->lock); | 1780 | spin_unlock(&vc->lock); |
1738 | 1781 | ||
1739 | kvm_guest_enter(); | 1782 | kvm_guest_enter(); |
@@ -1779,6 +1822,8 @@ static void kvmppc_run_core(struct kvmppc_vcore *vc) | |||
1779 | kvmppc_core_pending_dec(vcpu)) | 1822 | kvmppc_core_pending_dec(vcpu)) |
1780 | kvmppc_core_dequeue_dec(vcpu); | 1823 | kvmppc_core_dequeue_dec(vcpu); |
1781 | 1824 | ||
1825 | trace_kvm_guest_exit(vcpu); | ||
1826 | |||
1782 | ret = RESUME_GUEST; | 1827 | ret = RESUME_GUEST; |
1783 | if (vcpu->arch.trap) | 1828 | if (vcpu->arch.trap) |
1784 | ret = kvmppc_handle_exit_hv(vcpu->arch.kvm_run, vcpu, | 1829 | ret = kvmppc_handle_exit_hv(vcpu->arch.kvm_run, vcpu, |
@@ -1804,6 +1849,8 @@ static void kvmppc_run_core(struct kvmppc_vcore *vc) | |||
1804 | wake_up(&vcpu->arch.cpu_run); | 1849 | wake_up(&vcpu->arch.cpu_run); |
1805 | } | 1850 | } |
1806 | } | 1851 | } |
1852 | |||
1853 | trace_kvmppc_run_core(vc, 1); | ||
1807 | } | 1854 | } |
1808 | 1855 | ||
1809 | /* | 1856 | /* |
@@ -1826,15 +1873,37 @@ static void kvmppc_wait_for_exec(struct kvm_vcpu *vcpu, int wait_state) | |||
1826 | */ | 1873 | */ |
1827 | static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc) | 1874 | static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc) |
1828 | { | 1875 | { |
1876 | struct kvm_vcpu *vcpu; | ||
1877 | int do_sleep = 1; | ||
1878 | |||
1829 | DEFINE_WAIT(wait); | 1879 | DEFINE_WAIT(wait); |
1830 | 1880 | ||
1831 | prepare_to_wait(&vc->wq, &wait, TASK_INTERRUPTIBLE); | 1881 | prepare_to_wait(&vc->wq, &wait, TASK_INTERRUPTIBLE); |
1882 | |||
1883 | /* | ||
1884 | * Check one last time for pending exceptions and ceded state after | ||
1885 | * we put ourselves on the wait queue | ||
1886 | */ | ||
1887 | list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) { | ||
1888 | if (vcpu->arch.pending_exceptions || !vcpu->arch.ceded) { | ||
1889 | do_sleep = 0; | ||
1890 | break; | ||
1891 | } | ||
1892 | } | ||
1893 | |||
1894 | if (!do_sleep) { | ||
1895 | finish_wait(&vc->wq, &wait); | ||
1896 | return; | ||
1897 | } | ||
1898 | |||
1832 | vc->vcore_state = VCORE_SLEEPING; | 1899 | vc->vcore_state = VCORE_SLEEPING; |
1900 | trace_kvmppc_vcore_blocked(vc, 0); | ||
1833 | spin_unlock(&vc->lock); | 1901 | spin_unlock(&vc->lock); |
1834 | schedule(); | 1902 | schedule(); |
1835 | finish_wait(&vc->wq, &wait); | 1903 | finish_wait(&vc->wq, &wait); |
1836 | spin_lock(&vc->lock); | 1904 | spin_lock(&vc->lock); |
1837 | vc->vcore_state = VCORE_INACTIVE; | 1905 | vc->vcore_state = VCORE_INACTIVE; |
1906 | trace_kvmppc_vcore_blocked(vc, 1); | ||
1838 | } | 1907 | } |
1839 | 1908 | ||
1840 | static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | 1909 | static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) |
@@ -1843,6 +1912,8 @@ static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
1843 | struct kvmppc_vcore *vc; | 1912 | struct kvmppc_vcore *vc; |
1844 | struct kvm_vcpu *v, *vn; | 1913 | struct kvm_vcpu *v, *vn; |
1845 | 1914 | ||
1915 | trace_kvmppc_run_vcpu_enter(vcpu); | ||
1916 | |||
1846 | kvm_run->exit_reason = 0; | 1917 | kvm_run->exit_reason = 0; |
1847 | vcpu->arch.ret = RESUME_GUEST; | 1918 | vcpu->arch.ret = RESUME_GUEST; |
1848 | vcpu->arch.trap = 0; | 1919 | vcpu->arch.trap = 0; |
@@ -1872,6 +1943,7 @@ static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
1872 | VCORE_EXIT_COUNT(vc) == 0) { | 1943 | VCORE_EXIT_COUNT(vc) == 0) { |
1873 | kvmppc_create_dtl_entry(vcpu, vc); | 1944 | kvmppc_create_dtl_entry(vcpu, vc); |
1874 | kvmppc_start_thread(vcpu); | 1945 | kvmppc_start_thread(vcpu); |
1946 | trace_kvm_guest_enter(vcpu); | ||
1875 | } else if (vc->vcore_state == VCORE_SLEEPING) { | 1947 | } else if (vc->vcore_state == VCORE_SLEEPING) { |
1876 | wake_up(&vc->wq); | 1948 | wake_up(&vc->wq); |
1877 | } | 1949 | } |
@@ -1936,6 +2008,7 @@ static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
1936 | wake_up(&v->arch.cpu_run); | 2008 | wake_up(&v->arch.cpu_run); |
1937 | } | 2009 | } |
1938 | 2010 | ||
2011 | trace_kvmppc_run_vcpu_exit(vcpu, kvm_run); | ||
1939 | spin_unlock(&vc->lock); | 2012 | spin_unlock(&vc->lock); |
1940 | return vcpu->arch.ret; | 2013 | return vcpu->arch.ret; |
1941 | } | 2014 | } |
@@ -1962,7 +2035,7 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
1962 | /* Order vcpus_running vs. rma_setup_done, see kvmppc_alloc_reset_hpt */ | 2035 | /* Order vcpus_running vs. rma_setup_done, see kvmppc_alloc_reset_hpt */ |
1963 | smp_mb(); | 2036 | smp_mb(); |
1964 | 2037 | ||
1965 | /* On the first time here, set up HTAB and VRMA or RMA */ | 2038 | /* On the first time here, set up HTAB and VRMA */ |
1966 | if (!vcpu->kvm->arch.rma_setup_done) { | 2039 | if (!vcpu->kvm->arch.rma_setup_done) { |
1967 | r = kvmppc_hv_setup_htab_rma(vcpu); | 2040 | r = kvmppc_hv_setup_htab_rma(vcpu); |
1968 | if (r) | 2041 | if (r) |
@@ -1981,7 +2054,9 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
1981 | 2054 | ||
1982 | if (run->exit_reason == KVM_EXIT_PAPR_HCALL && | 2055 | if (run->exit_reason == KVM_EXIT_PAPR_HCALL && |
1983 | !(vcpu->arch.shregs.msr & MSR_PR)) { | 2056 | !(vcpu->arch.shregs.msr & MSR_PR)) { |
2057 | trace_kvm_hcall_enter(vcpu); | ||
1984 | r = kvmppc_pseries_do_hcall(vcpu); | 2058 | r = kvmppc_pseries_do_hcall(vcpu); |
2059 | trace_kvm_hcall_exit(vcpu, r); | ||
1985 | kvmppc_core_prepare_to_enter(vcpu); | 2060 | kvmppc_core_prepare_to_enter(vcpu); |
1986 | } else if (r == RESUME_PAGE_FAULT) { | 2061 | } else if (r == RESUME_PAGE_FAULT) { |
1987 | srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); | 2062 | srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); |
@@ -1997,98 +2072,6 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
1997 | return r; | 2072 | return r; |
1998 | } | 2073 | } |
1999 | 2074 | ||
2000 | |||
2001 | /* Work out RMLS (real mode limit selector) field value for a given RMA size. | ||
2002 | Assumes POWER7 or PPC970. */ | ||
2003 | static inline int lpcr_rmls(unsigned long rma_size) | ||
2004 | { | ||
2005 | switch (rma_size) { | ||
2006 | case 32ul << 20: /* 32 MB */ | ||
2007 | if (cpu_has_feature(CPU_FTR_ARCH_206)) | ||
2008 | return 8; /* only supported on POWER7 */ | ||
2009 | return -1; | ||
2010 | case 64ul << 20: /* 64 MB */ | ||
2011 | return 3; | ||
2012 | case 128ul << 20: /* 128 MB */ | ||
2013 | return 7; | ||
2014 | case 256ul << 20: /* 256 MB */ | ||
2015 | return 4; | ||
2016 | case 1ul << 30: /* 1 GB */ | ||
2017 | return 2; | ||
2018 | case 16ul << 30: /* 16 GB */ | ||
2019 | return 1; | ||
2020 | case 256ul << 30: /* 256 GB */ | ||
2021 | return 0; | ||
2022 | default: | ||
2023 | return -1; | ||
2024 | } | ||
2025 | } | ||
2026 | |||
2027 | static int kvm_rma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | ||
2028 | { | ||
2029 | struct page *page; | ||
2030 | struct kvm_rma_info *ri = vma->vm_file->private_data; | ||
2031 | |||
2032 | if (vmf->pgoff >= kvm_rma_pages) | ||
2033 | return VM_FAULT_SIGBUS; | ||
2034 | |||
2035 | page = pfn_to_page(ri->base_pfn + vmf->pgoff); | ||
2036 | get_page(page); | ||
2037 | vmf->page = page; | ||
2038 | return 0; | ||
2039 | } | ||
2040 | |||
2041 | static const struct vm_operations_struct kvm_rma_vm_ops = { | ||
2042 | .fault = kvm_rma_fault, | ||
2043 | }; | ||
2044 | |||
2045 | static int kvm_rma_mmap(struct file *file, struct vm_area_struct *vma) | ||
2046 | { | ||
2047 | vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; | ||
2048 | vma->vm_ops = &kvm_rma_vm_ops; | ||
2049 | return 0; | ||
2050 | } | ||
2051 | |||
2052 | static int kvm_rma_release(struct inode *inode, struct file *filp) | ||
2053 | { | ||
2054 | struct kvm_rma_info *ri = filp->private_data; | ||
2055 | |||
2056 | kvm_release_rma(ri); | ||
2057 | return 0; | ||
2058 | } | ||
2059 | |||
2060 | static const struct file_operations kvm_rma_fops = { | ||
2061 | .mmap = kvm_rma_mmap, | ||
2062 | .release = kvm_rma_release, | ||
2063 | }; | ||
2064 | |||
2065 | static long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, | ||
2066 | struct kvm_allocate_rma *ret) | ||
2067 | { | ||
2068 | long fd; | ||
2069 | struct kvm_rma_info *ri; | ||
2070 | /* | ||
2071 | * Only do this on PPC970 in HV mode | ||
2072 | */ | ||
2073 | if (!cpu_has_feature(CPU_FTR_HVMODE) || | ||
2074 | !cpu_has_feature(CPU_FTR_ARCH_201)) | ||
2075 | return -EINVAL; | ||
2076 | |||
2077 | if (!kvm_rma_pages) | ||
2078 | return -EINVAL; | ||
2079 | |||
2080 | ri = kvm_alloc_rma(); | ||
2081 | if (!ri) | ||
2082 | return -ENOMEM; | ||
2083 | |||
2084 | fd = anon_inode_getfd("kvm-rma", &kvm_rma_fops, ri, O_RDWR | O_CLOEXEC); | ||
2085 | if (fd < 0) | ||
2086 | kvm_release_rma(ri); | ||
2087 | |||
2088 | ret->rma_size = kvm_rma_pages << PAGE_SHIFT; | ||
2089 | return fd; | ||
2090 | } | ||
2091 | |||
2092 | static void kvmppc_add_seg_page_size(struct kvm_ppc_one_seg_page_size **sps, | 2075 | static void kvmppc_add_seg_page_size(struct kvm_ppc_one_seg_page_size **sps, |
2093 | int linux_psize) | 2076 | int linux_psize) |
2094 | { | 2077 | { |
@@ -2167,26 +2150,6 @@ out: | |||
2167 | return r; | 2150 | return r; |
2168 | } | 2151 | } |
2169 | 2152 | ||
2170 | static void unpin_slot(struct kvm_memory_slot *memslot) | ||
2171 | { | ||
2172 | unsigned long *physp; | ||
2173 | unsigned long j, npages, pfn; | ||
2174 | struct page *page; | ||
2175 | |||
2176 | physp = memslot->arch.slot_phys; | ||
2177 | npages = memslot->npages; | ||
2178 | if (!physp) | ||
2179 | return; | ||
2180 | for (j = 0; j < npages; j++) { | ||
2181 | if (!(physp[j] & KVMPPC_GOT_PAGE)) | ||
2182 | continue; | ||
2183 | pfn = physp[j] >> PAGE_SHIFT; | ||
2184 | page = pfn_to_page(pfn); | ||
2185 | SetPageDirty(page); | ||
2186 | put_page(page); | ||
2187 | } | ||
2188 | } | ||
2189 | |||
2190 | static void kvmppc_core_free_memslot_hv(struct kvm_memory_slot *free, | 2153 | static void kvmppc_core_free_memslot_hv(struct kvm_memory_slot *free, |
2191 | struct kvm_memory_slot *dont) | 2154 | struct kvm_memory_slot *dont) |
2192 | { | 2155 | { |
@@ -2194,11 +2157,6 @@ static void kvmppc_core_free_memslot_hv(struct kvm_memory_slot *free, | |||
2194 | vfree(free->arch.rmap); | 2157 | vfree(free->arch.rmap); |
2195 | free->arch.rmap = NULL; | 2158 | free->arch.rmap = NULL; |
2196 | } | 2159 | } |
2197 | if (!dont || free->arch.slot_phys != dont->arch.slot_phys) { | ||
2198 | unpin_slot(free); | ||
2199 | vfree(free->arch.slot_phys); | ||
2200 | free->arch.slot_phys = NULL; | ||
2201 | } | ||
2202 | } | 2160 | } |
2203 | 2161 | ||
2204 | static int kvmppc_core_create_memslot_hv(struct kvm_memory_slot *slot, | 2162 | static int kvmppc_core_create_memslot_hv(struct kvm_memory_slot *slot, |
@@ -2207,7 +2165,6 @@ static int kvmppc_core_create_memslot_hv(struct kvm_memory_slot *slot, | |||
2207 | slot->arch.rmap = vzalloc(npages * sizeof(*slot->arch.rmap)); | 2165 | slot->arch.rmap = vzalloc(npages * sizeof(*slot->arch.rmap)); |
2208 | if (!slot->arch.rmap) | 2166 | if (!slot->arch.rmap) |
2209 | return -ENOMEM; | 2167 | return -ENOMEM; |
2210 | slot->arch.slot_phys = NULL; | ||
2211 | 2168 | ||
2212 | return 0; | 2169 | return 0; |
2213 | } | 2170 | } |
@@ -2216,17 +2173,6 @@ static int kvmppc_core_prepare_memory_region_hv(struct kvm *kvm, | |||
2216 | struct kvm_memory_slot *memslot, | 2173 | struct kvm_memory_slot *memslot, |
2217 | struct kvm_userspace_memory_region *mem) | 2174 | struct kvm_userspace_memory_region *mem) |
2218 | { | 2175 | { |
2219 | unsigned long *phys; | ||
2220 | |||
2221 | /* Allocate a slot_phys array if needed */ | ||
2222 | phys = memslot->arch.slot_phys; | ||
2223 | if (!kvm->arch.using_mmu_notifiers && !phys && memslot->npages) { | ||
2224 | phys = vzalloc(memslot->npages * sizeof(unsigned long)); | ||
2225 | if (!phys) | ||
2226 | return -ENOMEM; | ||
2227 | memslot->arch.slot_phys = phys; | ||
2228 | } | ||
2229 | |||
2230 | return 0; | 2176 | return 0; |
2231 | } | 2177 | } |
2232 | 2178 | ||
@@ -2284,17 +2230,11 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu) | |||
2284 | { | 2230 | { |
2285 | int err = 0; | 2231 | int err = 0; |
2286 | struct kvm *kvm = vcpu->kvm; | 2232 | struct kvm *kvm = vcpu->kvm; |
2287 | struct kvm_rma_info *ri = NULL; | ||
2288 | unsigned long hva; | 2233 | unsigned long hva; |
2289 | struct kvm_memory_slot *memslot; | 2234 | struct kvm_memory_slot *memslot; |
2290 | struct vm_area_struct *vma; | 2235 | struct vm_area_struct *vma; |
2291 | unsigned long lpcr = 0, senc; | 2236 | unsigned long lpcr = 0, senc; |
2292 | unsigned long lpcr_mask = 0; | ||
2293 | unsigned long psize, porder; | 2237 | unsigned long psize, porder; |
2294 | unsigned long rma_size; | ||
2295 | unsigned long rmls; | ||
2296 | unsigned long *physp; | ||
2297 | unsigned long i, npages; | ||
2298 | int srcu_idx; | 2238 | int srcu_idx; |
2299 | 2239 | ||
2300 | mutex_lock(&kvm->lock); | 2240 | mutex_lock(&kvm->lock); |
@@ -2329,88 +2269,25 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu) | |||
2329 | psize = vma_kernel_pagesize(vma); | 2269 | psize = vma_kernel_pagesize(vma); |
2330 | porder = __ilog2(psize); | 2270 | porder = __ilog2(psize); |
2331 | 2271 | ||
2332 | /* Is this one of our preallocated RMAs? */ | ||
2333 | if (vma->vm_file && vma->vm_file->f_op == &kvm_rma_fops && | ||
2334 | hva == vma->vm_start) | ||
2335 | ri = vma->vm_file->private_data; | ||
2336 | |||
2337 | up_read(¤t->mm->mmap_sem); | 2272 | up_read(¤t->mm->mmap_sem); |
2338 | 2273 | ||
2339 | if (!ri) { | 2274 | /* We can handle 4k, 64k or 16M pages in the VRMA */ |
2340 | /* On POWER7, use VRMA; on PPC970, give up */ | 2275 | err = -EINVAL; |
2341 | err = -EPERM; | 2276 | if (!(psize == 0x1000 || psize == 0x10000 || |
2342 | if (cpu_has_feature(CPU_FTR_ARCH_201)) { | 2277 | psize == 0x1000000)) |
2343 | pr_err("KVM: CPU requires an RMO\n"); | 2278 | goto out_srcu; |
2344 | goto out_srcu; | ||
2345 | } | ||
2346 | 2279 | ||
2347 | /* We can handle 4k, 64k or 16M pages in the VRMA */ | 2280 | /* Update VRMASD field in the LPCR */ |
2348 | err = -EINVAL; | 2281 | senc = slb_pgsize_encoding(psize); |
2349 | if (!(psize == 0x1000 || psize == 0x10000 || | 2282 | kvm->arch.vrma_slb_v = senc | SLB_VSID_B_1T | |
2350 | psize == 0x1000000)) | 2283 | (VRMA_VSID << SLB_VSID_SHIFT_1T); |
2351 | goto out_srcu; | 2284 | /* the -4 is to account for senc values starting at 0x10 */ |
2285 | lpcr = senc << (LPCR_VRMASD_SH - 4); | ||
2352 | 2286 | ||
2353 | /* Update VRMASD field in the LPCR */ | 2287 | /* Create HPTEs in the hash page table for the VRMA */ |
2354 | senc = slb_pgsize_encoding(psize); | 2288 | kvmppc_map_vrma(vcpu, memslot, porder); |
2355 | kvm->arch.vrma_slb_v = senc | SLB_VSID_B_1T | | ||
2356 | (VRMA_VSID << SLB_VSID_SHIFT_1T); | ||
2357 | lpcr_mask = LPCR_VRMASD; | ||
2358 | /* the -4 is to account for senc values starting at 0x10 */ | ||
2359 | lpcr = senc << (LPCR_VRMASD_SH - 4); | ||
2360 | 2289 | ||
2361 | /* Create HPTEs in the hash page table for the VRMA */ | 2290 | kvmppc_update_lpcr(kvm, lpcr, LPCR_VRMASD); |
2362 | kvmppc_map_vrma(vcpu, memslot, porder); | ||
2363 | |||
2364 | } else { | ||
2365 | /* Set up to use an RMO region */ | ||
2366 | rma_size = kvm_rma_pages; | ||
2367 | if (rma_size > memslot->npages) | ||
2368 | rma_size = memslot->npages; | ||
2369 | rma_size <<= PAGE_SHIFT; | ||
2370 | rmls = lpcr_rmls(rma_size); | ||
2371 | err = -EINVAL; | ||
2372 | if ((long)rmls < 0) { | ||
2373 | pr_err("KVM: Can't use RMA of 0x%lx bytes\n", rma_size); | ||
2374 | goto out_srcu; | ||
2375 | } | ||
2376 | atomic_inc(&ri->use_count); | ||
2377 | kvm->arch.rma = ri; | ||
2378 | |||
2379 | /* Update LPCR and RMOR */ | ||
2380 | if (cpu_has_feature(CPU_FTR_ARCH_201)) { | ||
2381 | /* PPC970; insert RMLS value (split field) in HID4 */ | ||
2382 | lpcr_mask = (1ul << HID4_RMLS0_SH) | | ||
2383 | (3ul << HID4_RMLS2_SH) | HID4_RMOR; | ||
2384 | lpcr = ((rmls >> 2) << HID4_RMLS0_SH) | | ||
2385 | ((rmls & 3) << HID4_RMLS2_SH); | ||
2386 | /* RMOR is also in HID4 */ | ||
2387 | lpcr |= ((ri->base_pfn >> (26 - PAGE_SHIFT)) & 0xffff) | ||
2388 | << HID4_RMOR_SH; | ||
2389 | } else { | ||
2390 | /* POWER7 */ | ||
2391 | lpcr_mask = LPCR_VPM0 | LPCR_VRMA_L | LPCR_RMLS; | ||
2392 | lpcr = rmls << LPCR_RMLS_SH; | ||
2393 | kvm->arch.rmor = ri->base_pfn << PAGE_SHIFT; | ||
2394 | } | ||
2395 | pr_info("KVM: Using RMO at %lx size %lx (LPCR = %lx)\n", | ||
2396 | ri->base_pfn << PAGE_SHIFT, rma_size, lpcr); | ||
2397 | |||
2398 | /* Initialize phys addrs of pages in RMO */ | ||
2399 | npages = kvm_rma_pages; | ||
2400 | porder = __ilog2(npages); | ||
2401 | physp = memslot->arch.slot_phys; | ||
2402 | if (physp) { | ||
2403 | if (npages > memslot->npages) | ||
2404 | npages = memslot->npages; | ||
2405 | spin_lock(&kvm->arch.slot_phys_lock); | ||
2406 | for (i = 0; i < npages; ++i) | ||
2407 | physp[i] = ((ri->base_pfn + i) << PAGE_SHIFT) + | ||
2408 | porder; | ||
2409 | spin_unlock(&kvm->arch.slot_phys_lock); | ||
2410 | } | ||
2411 | } | ||
2412 | |||
2413 | kvmppc_update_lpcr(kvm, lpcr, lpcr_mask); | ||
2414 | 2291 | ||
2415 | /* Order updates to kvm->arch.lpcr etc. vs. rma_setup_done */ | 2292 | /* Order updates to kvm->arch.lpcr etc. vs. rma_setup_done */ |
2416 | smp_wmb(); | 2293 | smp_wmb(); |
@@ -2449,35 +2326,21 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm) | |||
2449 | memcpy(kvm->arch.enabled_hcalls, default_enabled_hcalls, | 2326 | memcpy(kvm->arch.enabled_hcalls, default_enabled_hcalls, |
2450 | sizeof(kvm->arch.enabled_hcalls)); | 2327 | sizeof(kvm->arch.enabled_hcalls)); |
2451 | 2328 | ||
2452 | kvm->arch.rma = NULL; | ||
2453 | |||
2454 | kvm->arch.host_sdr1 = mfspr(SPRN_SDR1); | 2329 | kvm->arch.host_sdr1 = mfspr(SPRN_SDR1); |
2455 | 2330 | ||
2456 | if (cpu_has_feature(CPU_FTR_ARCH_201)) { | 2331 | /* Init LPCR for virtual RMA mode */ |
2457 | /* PPC970; HID4 is effectively the LPCR */ | 2332 | kvm->arch.host_lpid = mfspr(SPRN_LPID); |
2458 | kvm->arch.host_lpid = 0; | 2333 | kvm->arch.host_lpcr = lpcr = mfspr(SPRN_LPCR); |
2459 | kvm->arch.host_lpcr = lpcr = mfspr(SPRN_HID4); | 2334 | lpcr &= LPCR_PECE | LPCR_LPES; |
2460 | lpcr &= ~((3 << HID4_LPID1_SH) | (0xful << HID4_LPID5_SH)); | 2335 | lpcr |= (4UL << LPCR_DPFD_SH) | LPCR_HDICE | |
2461 | lpcr |= ((lpid >> 4) << HID4_LPID1_SH) | | 2336 | LPCR_VPM0 | LPCR_VPM1; |
2462 | ((lpid & 0xf) << HID4_LPID5_SH); | 2337 | kvm->arch.vrma_slb_v = SLB_VSID_B_1T | |
2463 | } else { | 2338 | (VRMA_VSID << SLB_VSID_SHIFT_1T); |
2464 | /* POWER7; init LPCR for virtual RMA mode */ | 2339 | /* On POWER8 turn on online bit to enable PURR/SPURR */ |
2465 | kvm->arch.host_lpid = mfspr(SPRN_LPID); | 2340 | if (cpu_has_feature(CPU_FTR_ARCH_207S)) |
2466 | kvm->arch.host_lpcr = lpcr = mfspr(SPRN_LPCR); | 2341 | lpcr |= LPCR_ONL; |
2467 | lpcr &= LPCR_PECE | LPCR_LPES; | ||
2468 | lpcr |= (4UL << LPCR_DPFD_SH) | LPCR_HDICE | | ||
2469 | LPCR_VPM0 | LPCR_VPM1; | ||
2470 | kvm->arch.vrma_slb_v = SLB_VSID_B_1T | | ||
2471 | (VRMA_VSID << SLB_VSID_SHIFT_1T); | ||
2472 | /* On POWER8 turn on online bit to enable PURR/SPURR */ | ||
2473 | if (cpu_has_feature(CPU_FTR_ARCH_207S)) | ||
2474 | lpcr |= LPCR_ONL; | ||
2475 | } | ||
2476 | kvm->arch.lpcr = lpcr; | 2342 | kvm->arch.lpcr = lpcr; |
2477 | 2343 | ||
2478 | kvm->arch.using_mmu_notifiers = !!cpu_has_feature(CPU_FTR_ARCH_206); | ||
2479 | spin_lock_init(&kvm->arch.slot_phys_lock); | ||
2480 | |||
2481 | /* | 2344 | /* |
2482 | * Track that we now have a HV mode VM active. This blocks secondary | 2345 | * Track that we now have a HV mode VM active. This blocks secondary |
2483 | * CPU threads from coming online. | 2346 | * CPU threads from coming online. |
@@ -2507,10 +2370,6 @@ static void kvmppc_core_destroy_vm_hv(struct kvm *kvm) | |||
2507 | kvm_hv_vm_deactivated(); | 2370 | kvm_hv_vm_deactivated(); |
2508 | 2371 | ||
2509 | kvmppc_free_vcores(kvm); | 2372 | kvmppc_free_vcores(kvm); |
2510 | if (kvm->arch.rma) { | ||
2511 | kvm_release_rma(kvm->arch.rma); | ||
2512 | kvm->arch.rma = NULL; | ||
2513 | } | ||
2514 | 2373 | ||
2515 | kvmppc_free_hpt(kvm); | 2374 | kvmppc_free_hpt(kvm); |
2516 | } | 2375 | } |
@@ -2536,7 +2395,8 @@ static int kvmppc_core_emulate_mfspr_hv(struct kvm_vcpu *vcpu, int sprn, | |||
2536 | 2395 | ||
2537 | static int kvmppc_core_check_processor_compat_hv(void) | 2396 | static int kvmppc_core_check_processor_compat_hv(void) |
2538 | { | 2397 | { |
2539 | if (!cpu_has_feature(CPU_FTR_HVMODE)) | 2398 | if (!cpu_has_feature(CPU_FTR_HVMODE) || |
2399 | !cpu_has_feature(CPU_FTR_ARCH_206)) | ||
2540 | return -EIO; | 2400 | return -EIO; |
2541 | return 0; | 2401 | return 0; |
2542 | } | 2402 | } |
@@ -2550,16 +2410,6 @@ static long kvm_arch_vm_ioctl_hv(struct file *filp, | |||
2550 | 2410 | ||
2551 | switch (ioctl) { | 2411 | switch (ioctl) { |
2552 | 2412 | ||
2553 | case KVM_ALLOCATE_RMA: { | ||
2554 | struct kvm_allocate_rma rma; | ||
2555 | struct kvm *kvm = filp->private_data; | ||
2556 | |||
2557 | r = kvm_vm_ioctl_allocate_rma(kvm, &rma); | ||
2558 | if (r >= 0 && copy_to_user(argp, &rma, sizeof(rma))) | ||
2559 | r = -EFAULT; | ||
2560 | break; | ||
2561 | } | ||
2562 | |||
2563 | case KVM_PPC_ALLOCATE_HTAB: { | 2413 | case KVM_PPC_ALLOCATE_HTAB: { |
2564 | u32 htab_order; | 2414 | u32 htab_order; |
2565 | 2415 | ||
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index 3f1bb5a36c27..1f083ff8a61a 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/memblock.h> | 16 | #include <linux/memblock.h> |
17 | #include <linux/sizes.h> | 17 | #include <linux/sizes.h> |
18 | #include <linux/cma.h> | 18 | #include <linux/cma.h> |
19 | #include <linux/bitops.h> | ||
19 | 20 | ||
20 | #include <asm/cputable.h> | 21 | #include <asm/cputable.h> |
21 | #include <asm/kvm_ppc.h> | 22 | #include <asm/kvm_ppc.h> |
@@ -32,95 +33,9 @@ | |||
32 | * By default we reserve 5% of memory for hash pagetable allocation. | 33 | * By default we reserve 5% of memory for hash pagetable allocation. |
33 | */ | 34 | */ |
34 | static unsigned long kvm_cma_resv_ratio = 5; | 35 | static unsigned long kvm_cma_resv_ratio = 5; |
35 | /* | ||
36 | * We allocate RMAs (real mode areas) for KVM guests from the KVM CMA area. | ||
37 | * Each RMA has to be physically contiguous and of a size that the | ||
38 | * hardware supports. PPC970 and POWER7 support 64MB, 128MB and 256MB, | ||
39 | * and other larger sizes. Since we are unlikely to be allocate that | ||
40 | * much physically contiguous memory after the system is up and running, | ||
41 | * we preallocate a set of RMAs in early boot using CMA. | ||
42 | * should be power of 2. | ||
43 | */ | ||
44 | unsigned long kvm_rma_pages = (1 << 27) >> PAGE_SHIFT; /* 128MB */ | ||
45 | EXPORT_SYMBOL_GPL(kvm_rma_pages); | ||
46 | 36 | ||
47 | static struct cma *kvm_cma; | 37 | static struct cma *kvm_cma; |
48 | 38 | ||
49 | /* Work out RMLS (real mode limit selector) field value for a given RMA size. | ||
50 | Assumes POWER7 or PPC970. */ | ||
51 | static inline int lpcr_rmls(unsigned long rma_size) | ||
52 | { | ||
53 | switch (rma_size) { | ||
54 | case 32ul << 20: /* 32 MB */ | ||
55 | if (cpu_has_feature(CPU_FTR_ARCH_206)) | ||
56 | return 8; /* only supported on POWER7 */ | ||
57 | return -1; | ||
58 | case 64ul << 20: /* 64 MB */ | ||
59 | return 3; | ||
60 | case 128ul << 20: /* 128 MB */ | ||
61 | return 7; | ||
62 | case 256ul << 20: /* 256 MB */ | ||
63 | return 4; | ||
64 | case 1ul << 30: /* 1 GB */ | ||
65 | return 2; | ||
66 | case 16ul << 30: /* 16 GB */ | ||
67 | return 1; | ||
68 | case 256ul << 30: /* 256 GB */ | ||
69 | return 0; | ||
70 | default: | ||
71 | return -1; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | static int __init early_parse_rma_size(char *p) | ||
76 | { | ||
77 | unsigned long kvm_rma_size; | ||
78 | |||
79 | pr_debug("%s(%s)\n", __func__, p); | ||
80 | if (!p) | ||
81 | return -EINVAL; | ||
82 | kvm_rma_size = memparse(p, &p); | ||
83 | /* | ||
84 | * Check that the requested size is one supported in hardware | ||
85 | */ | ||
86 | if (lpcr_rmls(kvm_rma_size) < 0) { | ||
87 | pr_err("RMA size of 0x%lx not supported\n", kvm_rma_size); | ||
88 | return -EINVAL; | ||
89 | } | ||
90 | kvm_rma_pages = kvm_rma_size >> PAGE_SHIFT; | ||
91 | return 0; | ||
92 | } | ||
93 | early_param("kvm_rma_size", early_parse_rma_size); | ||
94 | |||
95 | struct kvm_rma_info *kvm_alloc_rma() | ||
96 | { | ||
97 | struct page *page; | ||
98 | struct kvm_rma_info *ri; | ||
99 | |||
100 | ri = kmalloc(sizeof(struct kvm_rma_info), GFP_KERNEL); | ||
101 | if (!ri) | ||
102 | return NULL; | ||
103 | page = cma_alloc(kvm_cma, kvm_rma_pages, order_base_2(kvm_rma_pages)); | ||
104 | if (!page) | ||
105 | goto err_out; | ||
106 | atomic_set(&ri->use_count, 1); | ||
107 | ri->base_pfn = page_to_pfn(page); | ||
108 | return ri; | ||
109 | err_out: | ||
110 | kfree(ri); | ||
111 | return NULL; | ||
112 | } | ||
113 | EXPORT_SYMBOL_GPL(kvm_alloc_rma); | ||
114 | |||
115 | void kvm_release_rma(struct kvm_rma_info *ri) | ||
116 | { | ||
117 | if (atomic_dec_and_test(&ri->use_count)) { | ||
118 | cma_release(kvm_cma, pfn_to_page(ri->base_pfn), kvm_rma_pages); | ||
119 | kfree(ri); | ||
120 | } | ||
121 | } | ||
122 | EXPORT_SYMBOL_GPL(kvm_release_rma); | ||
123 | |||
124 | static int __init early_parse_kvm_cma_resv(char *p) | 39 | static int __init early_parse_kvm_cma_resv(char *p) |
125 | { | 40 | { |
126 | pr_debug("%s(%s)\n", __func__, p); | 41 | pr_debug("%s(%s)\n", __func__, p); |
@@ -132,14 +47,9 @@ early_param("kvm_cma_resv_ratio", early_parse_kvm_cma_resv); | |||
132 | 47 | ||
133 | struct page *kvm_alloc_hpt(unsigned long nr_pages) | 48 | struct page *kvm_alloc_hpt(unsigned long nr_pages) |
134 | { | 49 | { |
135 | unsigned long align_pages = HPT_ALIGN_PAGES; | ||
136 | |||
137 | VM_BUG_ON(order_base_2(nr_pages) < KVM_CMA_CHUNK_ORDER - PAGE_SHIFT); | 50 | VM_BUG_ON(order_base_2(nr_pages) < KVM_CMA_CHUNK_ORDER - PAGE_SHIFT); |
138 | 51 | ||
139 | /* Old CPUs require HPT aligned on a multiple of its size */ | 52 | return cma_alloc(kvm_cma, nr_pages, order_base_2(HPT_ALIGN_PAGES)); |
140 | if (!cpu_has_feature(CPU_FTR_ARCH_206)) | ||
141 | align_pages = nr_pages; | ||
142 | return cma_alloc(kvm_cma, nr_pages, order_base_2(align_pages)); | ||
143 | } | 53 | } |
144 | EXPORT_SYMBOL_GPL(kvm_alloc_hpt); | 54 | EXPORT_SYMBOL_GPL(kvm_alloc_hpt); |
145 | 55 | ||
@@ -180,22 +90,44 @@ void __init kvm_cma_reserve(void) | |||
180 | if (selected_size) { | 90 | if (selected_size) { |
181 | pr_debug("%s: reserving %ld MiB for global area\n", __func__, | 91 | pr_debug("%s: reserving %ld MiB for global area\n", __func__, |
182 | (unsigned long)selected_size / SZ_1M); | 92 | (unsigned long)selected_size / SZ_1M); |
183 | /* | 93 | align_size = HPT_ALIGN_PAGES << PAGE_SHIFT; |
184 | * Old CPUs require HPT aligned on a multiple of its size. So for them | ||
185 | * make the alignment as max size we could request. | ||
186 | */ | ||
187 | if (!cpu_has_feature(CPU_FTR_ARCH_206)) | ||
188 | align_size = __rounddown_pow_of_two(selected_size); | ||
189 | else | ||
190 | align_size = HPT_ALIGN_PAGES << PAGE_SHIFT; | ||
191 | |||
192 | align_size = max(kvm_rma_pages << PAGE_SHIFT, align_size); | ||
193 | cma_declare_contiguous(0, selected_size, 0, align_size, | 94 | cma_declare_contiguous(0, selected_size, 0, align_size, |
194 | KVM_CMA_CHUNK_ORDER - PAGE_SHIFT, false, &kvm_cma); | 95 | KVM_CMA_CHUNK_ORDER - PAGE_SHIFT, false, &kvm_cma); |
195 | } | 96 | } |
196 | } | 97 | } |
197 | 98 | ||
198 | /* | 99 | /* |
100 | * Real-mode H_CONFER implementation. | ||
101 | * We check if we are the only vcpu out of this virtual core | ||
102 | * still running in the guest and not ceded. If so, we pop up | ||
103 | * to the virtual-mode implementation; if not, just return to | ||
104 | * the guest. | ||
105 | */ | ||
106 | long int kvmppc_rm_h_confer(struct kvm_vcpu *vcpu, int target, | ||
107 | unsigned int yield_count) | ||
108 | { | ||
109 | struct kvmppc_vcore *vc = vcpu->arch.vcore; | ||
110 | int threads_running; | ||
111 | int threads_ceded; | ||
112 | int threads_conferring; | ||
113 | u64 stop = get_tb() + 10 * tb_ticks_per_usec; | ||
114 | int rv = H_SUCCESS; /* => don't yield */ | ||
115 | |||
116 | set_bit(vcpu->arch.ptid, &vc->conferring_threads); | ||
117 | while ((get_tb() < stop) && (VCORE_EXIT_COUNT(vc) == 0)) { | ||
118 | threads_running = VCORE_ENTRY_COUNT(vc); | ||
119 | threads_ceded = hweight32(vc->napping_threads); | ||
120 | threads_conferring = hweight32(vc->conferring_threads); | ||
121 | if (threads_ceded + threads_conferring >= threads_running) { | ||
122 | rv = H_TOO_HARD; /* => do yield */ | ||
123 | break; | ||
124 | } | ||
125 | } | ||
126 | clear_bit(vcpu->arch.ptid, &vc->conferring_threads); | ||
127 | return rv; | ||
128 | } | ||
129 | |||
130 | /* | ||
199 | * When running HV mode KVM we need to block certain operations while KVM VMs | 131 | * When running HV mode KVM we need to block certain operations while KVM VMs |
200 | * exist in the system. We use a counter of VMs to track this. | 132 | * exist in the system. We use a counter of VMs to track this. |
201 | * | 133 | * |
diff --git a/arch/powerpc/kvm/book3s_hv_interrupts.S b/arch/powerpc/kvm/book3s_hv_interrupts.S index 731be7478b27..36540a99d178 100644 --- a/arch/powerpc/kvm/book3s_hv_interrupts.S +++ b/arch/powerpc/kvm/book3s_hv_interrupts.S | |||
@@ -52,10 +52,8 @@ _GLOBAL(__kvmppc_vcore_entry) | |||
52 | std r3, _CCR(r1) | 52 | std r3, _CCR(r1) |
53 | 53 | ||
54 | /* Save host DSCR */ | 54 | /* Save host DSCR */ |
55 | BEGIN_FTR_SECTION | ||
56 | mfspr r3, SPRN_DSCR | 55 | mfspr r3, SPRN_DSCR |
57 | std r3, HSTATE_DSCR(r13) | 56 | std r3, HSTATE_DSCR(r13) |
58 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) | ||
59 | 57 | ||
60 | BEGIN_FTR_SECTION | 58 | BEGIN_FTR_SECTION |
61 | /* Save host DABR */ | 59 | /* Save host DABR */ |
@@ -84,11 +82,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) | |||
84 | mfspr r7, SPRN_MMCR0 /* save MMCR0 */ | 82 | mfspr r7, SPRN_MMCR0 /* save MMCR0 */ |
85 | mtspr SPRN_MMCR0, r3 /* freeze all counters, disable interrupts */ | 83 | mtspr SPRN_MMCR0, r3 /* freeze all counters, disable interrupts */ |
86 | mfspr r6, SPRN_MMCRA | 84 | mfspr r6, SPRN_MMCRA |
87 | BEGIN_FTR_SECTION | 85 | /* Clear MMCRA in order to disable SDAR updates */ |
88 | /* On P7, clear MMCRA in order to disable SDAR updates */ | ||
89 | li r5, 0 | 86 | li r5, 0 |
90 | mtspr SPRN_MMCRA, r5 | 87 | mtspr SPRN_MMCRA, r5 |
91 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) | ||
92 | isync | 88 | isync |
93 | ld r3, PACALPPACAPTR(r13) /* is the host using the PMU? */ | 89 | ld r3, PACALPPACAPTR(r13) /* is the host using the PMU? */ |
94 | lbz r5, LPPACA_PMCINUSE(r3) | 90 | lbz r5, LPPACA_PMCINUSE(r3) |
@@ -113,20 +109,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) | |||
113 | mfspr r7, SPRN_PMC4 | 109 | mfspr r7, SPRN_PMC4 |
114 | mfspr r8, SPRN_PMC5 | 110 | mfspr r8, SPRN_PMC5 |
115 | mfspr r9, SPRN_PMC6 | 111 | mfspr r9, SPRN_PMC6 |
116 | BEGIN_FTR_SECTION | ||
117 | mfspr r10, SPRN_PMC7 | ||
118 | mfspr r11, SPRN_PMC8 | ||
119 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) | ||
120 | stw r3, HSTATE_PMC(r13) | 112 | stw r3, HSTATE_PMC(r13) |
121 | stw r5, HSTATE_PMC + 4(r13) | 113 | stw r5, HSTATE_PMC + 4(r13) |
122 | stw r6, HSTATE_PMC + 8(r13) | 114 | stw r6, HSTATE_PMC + 8(r13) |
123 | stw r7, HSTATE_PMC + 12(r13) | 115 | stw r7, HSTATE_PMC + 12(r13) |
124 | stw r8, HSTATE_PMC + 16(r13) | 116 | stw r8, HSTATE_PMC + 16(r13) |
125 | stw r9, HSTATE_PMC + 20(r13) | 117 | stw r9, HSTATE_PMC + 20(r13) |
126 | BEGIN_FTR_SECTION | ||
127 | stw r10, HSTATE_PMC + 24(r13) | ||
128 | stw r11, HSTATE_PMC + 28(r13) | ||
129 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) | ||
130 | 31: | 118 | 31: |
131 | 119 | ||
132 | /* | 120 | /* |
@@ -140,31 +128,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) | |||
140 | add r8,r8,r7 | 128 | add r8,r8,r7 |
141 | std r8,HSTATE_DECEXP(r13) | 129 | std r8,HSTATE_DECEXP(r13) |
142 | 130 | ||
143 | #ifdef CONFIG_SMP | ||
144 | /* | ||
145 | * On PPC970, if the guest vcpu has an external interrupt pending, | ||
146 | * send ourselves an IPI so as to interrupt the guest once it | ||
147 | * enables interrupts. (It must have interrupts disabled, | ||
148 | * otherwise we would already have delivered the interrupt.) | ||
149 | * | ||
150 | * XXX If this is a UP build, smp_send_reschedule is not available, | ||
151 | * so the interrupt will be delayed until the next time the vcpu | ||
152 | * enters the guest with interrupts enabled. | ||
153 | */ | ||
154 | BEGIN_FTR_SECTION | ||
155 | ld r4, HSTATE_KVM_VCPU(r13) | ||
156 | ld r0, VCPU_PENDING_EXC(r4) | ||
157 | li r7, (1 << BOOK3S_IRQPRIO_EXTERNAL) | ||
158 | oris r7, r7, (1 << BOOK3S_IRQPRIO_EXTERNAL_LEVEL)@h | ||
159 | and. r0, r0, r7 | ||
160 | beq 32f | ||
161 | lhz r3, PACAPACAINDEX(r13) | ||
162 | bl smp_send_reschedule | ||
163 | nop | ||
164 | 32: | ||
165 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) | ||
166 | #endif /* CONFIG_SMP */ | ||
167 | |||
168 | /* Jump to partition switch code */ | 131 | /* Jump to partition switch code */ |
169 | bl kvmppc_hv_entry_trampoline | 132 | bl kvmppc_hv_entry_trampoline |
170 | nop | 133 | nop |
diff --git a/arch/powerpc/kvm/book3s_hv_ras.c b/arch/powerpc/kvm/book3s_hv_ras.c index d562c8e2bc30..60081bd75847 100644 --- a/arch/powerpc/kvm/book3s_hv_ras.c +++ b/arch/powerpc/kvm/book3s_hv_ras.c | |||
@@ -138,8 +138,5 @@ out: | |||
138 | 138 | ||
139 | long kvmppc_realmode_machine_check(struct kvm_vcpu *vcpu) | 139 | long kvmppc_realmode_machine_check(struct kvm_vcpu *vcpu) |
140 | { | 140 | { |
141 | if (cpu_has_feature(CPU_FTR_ARCH_206)) | 141 | return kvmppc_realmode_mc_power7(vcpu); |
142 | return kvmppc_realmode_mc_power7(vcpu); | ||
143 | |||
144 | return 0; | ||
145 | } | 142 | } |
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index 084ad54c73cd..510bdfbc4073 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c | |||
@@ -45,16 +45,12 @@ static int global_invalidates(struct kvm *kvm, unsigned long flags) | |||
45 | * as indicated by local_paca->kvm_hstate.kvm_vcpu being set, | 45 | * as indicated by local_paca->kvm_hstate.kvm_vcpu being set, |
46 | * we can use tlbiel as long as we mark all other physical | 46 | * we can use tlbiel as long as we mark all other physical |
47 | * cores as potentially having stale TLB entries for this lpid. | 47 | * cores as potentially having stale TLB entries for this lpid. |
48 | * If we're not using MMU notifiers, we never take pages away | ||
49 | * from the guest, so we can use tlbiel if requested. | ||
50 | * Otherwise, don't use tlbiel. | 48 | * Otherwise, don't use tlbiel. |
51 | */ | 49 | */ |
52 | if (kvm->arch.online_vcores == 1 && local_paca->kvm_hstate.kvm_vcpu) | 50 | if (kvm->arch.online_vcores == 1 && local_paca->kvm_hstate.kvm_vcpu) |
53 | global = 0; | 51 | global = 0; |
54 | else if (kvm->arch.using_mmu_notifiers) | ||
55 | global = 1; | ||
56 | else | 52 | else |
57 | global = !(flags & H_LOCAL); | 53 | global = 1; |
58 | 54 | ||
59 | if (!global) { | 55 | if (!global) { |
60 | /* any other core might now have stale TLB entries... */ | 56 | /* any other core might now have stale TLB entries... */ |
@@ -170,7 +166,7 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, | |||
170 | struct revmap_entry *rev; | 166 | struct revmap_entry *rev; |
171 | unsigned long g_ptel; | 167 | unsigned long g_ptel; |
172 | struct kvm_memory_slot *memslot; | 168 | struct kvm_memory_slot *memslot; |
173 | unsigned long *physp, pte_size; | 169 | unsigned long pte_size; |
174 | unsigned long is_io; | 170 | unsigned long is_io; |
175 | unsigned long *rmap; | 171 | unsigned long *rmap; |
176 | pte_t pte; | 172 | pte_t pte; |
@@ -198,9 +194,6 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, | |||
198 | is_io = ~0ul; | 194 | is_io = ~0ul; |
199 | rmap = NULL; | 195 | rmap = NULL; |
200 | if (!(memslot && !(memslot->flags & KVM_MEMSLOT_INVALID))) { | 196 | if (!(memslot && !(memslot->flags & KVM_MEMSLOT_INVALID))) { |
201 | /* PPC970 can't do emulated MMIO */ | ||
202 | if (!cpu_has_feature(CPU_FTR_ARCH_206)) | ||
203 | return H_PARAMETER; | ||
204 | /* Emulated MMIO - mark this with key=31 */ | 197 | /* Emulated MMIO - mark this with key=31 */ |
205 | pteh |= HPTE_V_ABSENT; | 198 | pteh |= HPTE_V_ABSENT; |
206 | ptel |= HPTE_R_KEY_HI | HPTE_R_KEY_LO; | 199 | ptel |= HPTE_R_KEY_HI | HPTE_R_KEY_LO; |
@@ -213,37 +206,20 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, | |||
213 | slot_fn = gfn - memslot->base_gfn; | 206 | slot_fn = gfn - memslot->base_gfn; |
214 | rmap = &memslot->arch.rmap[slot_fn]; | 207 | rmap = &memslot->arch.rmap[slot_fn]; |
215 | 208 | ||
216 | if (!kvm->arch.using_mmu_notifiers) { | 209 | /* Translate to host virtual address */ |
217 | physp = memslot->arch.slot_phys; | 210 | hva = __gfn_to_hva_memslot(memslot, gfn); |
218 | if (!physp) | 211 | |
219 | return H_PARAMETER; | 212 | /* Look up the Linux PTE for the backing page */ |
220 | physp += slot_fn; | 213 | pte_size = psize; |
221 | if (realmode) | 214 | pte = lookup_linux_pte_and_update(pgdir, hva, writing, &pte_size); |
222 | physp = real_vmalloc_addr(physp); | 215 | if (pte_present(pte) && !pte_numa(pte)) { |
223 | pa = *physp; | 216 | if (writing && !pte_write(pte)) |
224 | if (!pa) | 217 | /* make the actual HPTE be read-only */ |
225 | return H_TOO_HARD; | 218 | ptel = hpte_make_readonly(ptel); |
226 | is_io = pa & (HPTE_R_I | HPTE_R_W); | 219 | is_io = hpte_cache_bits(pte_val(pte)); |
227 | pte_size = PAGE_SIZE << (pa & KVMPPC_PAGE_ORDER_MASK); | 220 | pa = pte_pfn(pte) << PAGE_SHIFT; |
228 | pa &= PAGE_MASK; | 221 | pa |= hva & (pte_size - 1); |
229 | pa |= gpa & ~PAGE_MASK; | 222 | pa |= gpa & ~PAGE_MASK; |
230 | } else { | ||
231 | /* Translate to host virtual address */ | ||
232 | hva = __gfn_to_hva_memslot(memslot, gfn); | ||
233 | |||
234 | /* Look up the Linux PTE for the backing page */ | ||
235 | pte_size = psize; | ||
236 | pte = lookup_linux_pte_and_update(pgdir, hva, writing, | ||
237 | &pte_size); | ||
238 | if (pte_present(pte) && !pte_numa(pte)) { | ||
239 | if (writing && !pte_write(pte)) | ||
240 | /* make the actual HPTE be read-only */ | ||
241 | ptel = hpte_make_readonly(ptel); | ||
242 | is_io = hpte_cache_bits(pte_val(pte)); | ||
243 | pa = pte_pfn(pte) << PAGE_SHIFT; | ||
244 | pa |= hva & (pte_size - 1); | ||
245 | pa |= gpa & ~PAGE_MASK; | ||
246 | } | ||
247 | } | 223 | } |
248 | 224 | ||
249 | if (pte_size < psize) | 225 | if (pte_size < psize) |
@@ -337,8 +313,7 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, | |||
337 | rmap = real_vmalloc_addr(rmap); | 313 | rmap = real_vmalloc_addr(rmap); |
338 | lock_rmap(rmap); | 314 | lock_rmap(rmap); |
339 | /* Check for pending invalidations under the rmap chain lock */ | 315 | /* Check for pending invalidations under the rmap chain lock */ |
340 | if (kvm->arch.using_mmu_notifiers && | 316 | if (mmu_notifier_retry(kvm, mmu_seq)) { |
341 | mmu_notifier_retry(kvm, mmu_seq)) { | ||
342 | /* inval in progress, write a non-present HPTE */ | 317 | /* inval in progress, write a non-present HPTE */ |
343 | pteh |= HPTE_V_ABSENT; | 318 | pteh |= HPTE_V_ABSENT; |
344 | pteh &= ~HPTE_V_VALID; | 319 | pteh &= ~HPTE_V_VALID; |
@@ -395,61 +370,11 @@ static inline int try_lock_tlbie(unsigned int *lock) | |||
395 | return old == 0; | 370 | return old == 0; |
396 | } | 371 | } |
397 | 372 | ||
398 | /* | ||
399 | * tlbie/tlbiel is a bit different on the PPC970 compared to later | ||
400 | * processors such as POWER7; the large page bit is in the instruction | ||
401 | * not RB, and the top 16 bits and the bottom 12 bits of the VA | ||
402 | * in RB must be 0. | ||
403 | */ | ||
404 | static void do_tlbies_970(struct kvm *kvm, unsigned long *rbvalues, | ||
405 | long npages, int global, bool need_sync) | ||
406 | { | ||
407 | long i; | ||
408 | |||
409 | if (global) { | ||
410 | while (!try_lock_tlbie(&kvm->arch.tlbie_lock)) | ||
411 | cpu_relax(); | ||
412 | if (need_sync) | ||
413 | asm volatile("ptesync" : : : "memory"); | ||
414 | for (i = 0; i < npages; ++i) { | ||
415 | unsigned long rb = rbvalues[i]; | ||
416 | |||
417 | if (rb & 1) /* large page */ | ||
418 | asm volatile("tlbie %0,1" : : | ||
419 | "r" (rb & 0x0000fffffffff000ul)); | ||
420 | else | ||
421 | asm volatile("tlbie %0,0" : : | ||
422 | "r" (rb & 0x0000fffffffff000ul)); | ||
423 | } | ||
424 | asm volatile("eieio; tlbsync; ptesync" : : : "memory"); | ||
425 | kvm->arch.tlbie_lock = 0; | ||
426 | } else { | ||
427 | if (need_sync) | ||
428 | asm volatile("ptesync" : : : "memory"); | ||
429 | for (i = 0; i < npages; ++i) { | ||
430 | unsigned long rb = rbvalues[i]; | ||
431 | |||
432 | if (rb & 1) /* large page */ | ||
433 | asm volatile("tlbiel %0,1" : : | ||
434 | "r" (rb & 0x0000fffffffff000ul)); | ||
435 | else | ||
436 | asm volatile("tlbiel %0,0" : : | ||
437 | "r" (rb & 0x0000fffffffff000ul)); | ||
438 | } | ||
439 | asm volatile("ptesync" : : : "memory"); | ||
440 | } | ||
441 | } | ||
442 | |||
443 | static void do_tlbies(struct kvm *kvm, unsigned long *rbvalues, | 373 | static void do_tlbies(struct kvm *kvm, unsigned long *rbvalues, |
444 | long npages, int global, bool need_sync) | 374 | long npages, int global, bool need_sync) |
445 | { | 375 | { |
446 | long i; | 376 | long i; |
447 | 377 | ||
448 | if (cpu_has_feature(CPU_FTR_ARCH_201)) { | ||
449 | /* PPC970 tlbie instruction is a bit different */ | ||
450 | do_tlbies_970(kvm, rbvalues, npages, global, need_sync); | ||
451 | return; | ||
452 | } | ||
453 | if (global) { | 378 | if (global) { |
454 | while (!try_lock_tlbie(&kvm->arch.tlbie_lock)) | 379 | while (!try_lock_tlbie(&kvm->arch.tlbie_lock)) |
455 | cpu_relax(); | 380 | cpu_relax(); |
@@ -667,40 +592,29 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags, | |||
667 | rev->guest_rpte = r; | 592 | rev->guest_rpte = r; |
668 | note_hpte_modification(kvm, rev); | 593 | note_hpte_modification(kvm, rev); |
669 | } | 594 | } |
670 | r = (be64_to_cpu(hpte[1]) & ~mask) | bits; | ||
671 | 595 | ||
672 | /* Update HPTE */ | 596 | /* Update HPTE */ |
673 | if (v & HPTE_V_VALID) { | 597 | if (v & HPTE_V_VALID) { |
674 | rb = compute_tlbie_rb(v, r, pte_index); | ||
675 | hpte[0] = cpu_to_be64(v & ~HPTE_V_VALID); | ||
676 | do_tlbies(kvm, &rb, 1, global_invalidates(kvm, flags), true); | ||
677 | /* | 598 | /* |
678 | * If the host has this page as readonly but the guest | 599 | * If the page is valid, don't let it transition from |
679 | * wants to make it read/write, reduce the permissions. | 600 | * readonly to writable. If it should be writable, we'll |
680 | * Checking the host permissions involves finding the | 601 | * take a trap and let the page fault code sort it out. |
681 | * memslot and then the Linux PTE for the page. | ||
682 | */ | 602 | */ |
683 | if (hpte_is_writable(r) && kvm->arch.using_mmu_notifiers) { | 603 | pte = be64_to_cpu(hpte[1]); |
684 | unsigned long psize, gfn, hva; | 604 | r = (pte & ~mask) | bits; |
685 | struct kvm_memory_slot *memslot; | 605 | if (hpte_is_writable(r) && !hpte_is_writable(pte)) |
686 | pgd_t *pgdir = vcpu->arch.pgdir; | 606 | r = hpte_make_readonly(r); |
687 | pte_t pte; | 607 | /* If the PTE is changing, invalidate it first */ |
688 | 608 | if (r != pte) { | |
689 | psize = hpte_page_size(v, r); | 609 | rb = compute_tlbie_rb(v, r, pte_index); |
690 | gfn = ((r & HPTE_R_RPN) & ~(psize - 1)) >> PAGE_SHIFT; | 610 | hpte[0] = cpu_to_be64((v & ~HPTE_V_VALID) | |
691 | memslot = __gfn_to_memslot(kvm_memslots_raw(kvm), gfn); | 611 | HPTE_V_ABSENT); |
692 | if (memslot) { | 612 | do_tlbies(kvm, &rb, 1, global_invalidates(kvm, flags), |
693 | hva = __gfn_to_hva_memslot(memslot, gfn); | 613 | true); |
694 | pte = lookup_linux_pte_and_update(pgdir, hva, | 614 | hpte[1] = cpu_to_be64(r); |
695 | 1, &psize); | ||
696 | if (pte_present(pte) && !pte_write(pte)) | ||
697 | r = hpte_make_readonly(r); | ||
698 | } | ||
699 | } | 615 | } |
700 | } | 616 | } |
701 | hpte[1] = cpu_to_be64(r); | 617 | unlock_hpte(hpte, v & ~HPTE_V_HVLOCK); |
702 | eieio(); | ||
703 | hpte[0] = cpu_to_be64(v & ~HPTE_V_HVLOCK); | ||
704 | asm volatile("ptesync" : : : "memory"); | 618 | asm volatile("ptesync" : : : "memory"); |
705 | return H_SUCCESS; | 619 | return H_SUCCESS; |
706 | } | 620 | } |
diff --git a/arch/powerpc/kvm/book3s_hv_rm_xics.c b/arch/powerpc/kvm/book3s_hv_rm_xics.c index 3ee38e6e884f..7b066f6b02ad 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_xics.c +++ b/arch/powerpc/kvm/book3s_hv_rm_xics.c | |||
@@ -183,8 +183,10 @@ static void icp_rm_down_cppr(struct kvmppc_xics *xics, struct kvmppc_icp *icp, | |||
183 | * state update in HW (ie bus transactions) so we can handle them | 183 | * state update in HW (ie bus transactions) so we can handle them |
184 | * separately here as well. | 184 | * separately here as well. |
185 | */ | 185 | */ |
186 | if (resend) | 186 | if (resend) { |
187 | icp->rm_action |= XICS_RM_CHECK_RESEND; | 187 | icp->rm_action |= XICS_RM_CHECK_RESEND; |
188 | icp->rm_resend_icp = icp; | ||
189 | } | ||
188 | } | 190 | } |
189 | 191 | ||
190 | 192 | ||
@@ -254,10 +256,25 @@ int kvmppc_rm_h_ipi(struct kvm_vcpu *vcpu, unsigned long server, | |||
254 | * nothing needs to be done as there can be no XISR to | 256 | * nothing needs to be done as there can be no XISR to |
255 | * reject. | 257 | * reject. |
256 | * | 258 | * |
259 | * ICP state: Check_IPI | ||
260 | * | ||
257 | * If the CPPR is less favored, then we might be replacing | 261 | * If the CPPR is less favored, then we might be replacing |
258 | * an interrupt, and thus need to possibly reject it as in | 262 | * an interrupt, and thus need to possibly reject it. |
259 | * | 263 | * |
260 | * ICP state: Check_IPI | 264 | * ICP State: IPI |
265 | * | ||
266 | * Besides rejecting any pending interrupts, we also | ||
267 | * update XISR and pending_pri to mark IPI as pending. | ||
268 | * | ||
269 | * PAPR does not describe this state, but if the MFRR is being | ||
270 | * made less favored than its earlier value, there might be | ||
271 | * a previously-rejected interrupt needing to be resent. | ||
272 | * Ideally, we would want to resend only if | ||
273 | * prio(pending_interrupt) < mfrr && | ||
274 | * prio(pending_interrupt) < cppr | ||
275 | * where pending interrupt is the one that was rejected. But | ||
276 | * we don't have that state, so we simply trigger a resend | ||
277 | * whenever the MFRR is made less favored. | ||
261 | */ | 278 | */ |
262 | do { | 279 | do { |
263 | old_state = new_state = ACCESS_ONCE(icp->state); | 280 | old_state = new_state = ACCESS_ONCE(icp->state); |
@@ -270,13 +287,14 @@ int kvmppc_rm_h_ipi(struct kvm_vcpu *vcpu, unsigned long server, | |||
270 | resend = false; | 287 | resend = false; |
271 | if (mfrr < new_state.cppr) { | 288 | if (mfrr < new_state.cppr) { |
272 | /* Reject a pending interrupt if not an IPI */ | 289 | /* Reject a pending interrupt if not an IPI */ |
273 | if (mfrr <= new_state.pending_pri) | 290 | if (mfrr <= new_state.pending_pri) { |
274 | reject = new_state.xisr; | 291 | reject = new_state.xisr; |
275 | new_state.pending_pri = mfrr; | 292 | new_state.pending_pri = mfrr; |
276 | new_state.xisr = XICS_IPI; | 293 | new_state.xisr = XICS_IPI; |
294 | } | ||
277 | } | 295 | } |
278 | 296 | ||
279 | if (mfrr > old_state.mfrr && mfrr > new_state.cppr) { | 297 | if (mfrr > old_state.mfrr) { |
280 | resend = new_state.need_resend; | 298 | resend = new_state.need_resend; |
281 | new_state.need_resend = 0; | 299 | new_state.need_resend = 0; |
282 | } | 300 | } |
@@ -289,8 +307,10 @@ int kvmppc_rm_h_ipi(struct kvm_vcpu *vcpu, unsigned long server, | |||
289 | } | 307 | } |
290 | 308 | ||
291 | /* Pass resends to virtual mode */ | 309 | /* Pass resends to virtual mode */ |
292 | if (resend) | 310 | if (resend) { |
293 | this_icp->rm_action |= XICS_RM_CHECK_RESEND; | 311 | this_icp->rm_action |= XICS_RM_CHECK_RESEND; |
312 | this_icp->rm_resend_icp = icp; | ||
313 | } | ||
294 | 314 | ||
295 | return check_too_hard(xics, this_icp); | 315 | return check_too_hard(xics, this_icp); |
296 | } | 316 | } |
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 65c105b17a25..10554df13852 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S | |||
@@ -94,20 +94,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_PMAO_BUG) | |||
94 | lwz r6, HSTATE_PMC + 12(r13) | 94 | lwz r6, HSTATE_PMC + 12(r13) |
95 | lwz r8, HSTATE_PMC + 16(r13) | 95 | lwz r8, HSTATE_PMC + 16(r13) |
96 | lwz r9, HSTATE_PMC + 20(r13) | 96 | lwz r9, HSTATE_PMC + 20(r13) |
97 | BEGIN_FTR_SECTION | ||
98 | lwz r10, HSTATE_PMC + 24(r13) | ||
99 | lwz r11, HSTATE_PMC + 28(r13) | ||
100 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) | ||
101 | mtspr SPRN_PMC1, r3 | 97 | mtspr SPRN_PMC1, r3 |
102 | mtspr SPRN_PMC2, r4 | 98 | mtspr SPRN_PMC2, r4 |
103 | mtspr SPRN_PMC3, r5 | 99 | mtspr SPRN_PMC3, r5 |
104 | mtspr SPRN_PMC4, r6 | 100 | mtspr SPRN_PMC4, r6 |
105 | mtspr SPRN_PMC5, r8 | 101 | mtspr SPRN_PMC5, r8 |
106 | mtspr SPRN_PMC6, r9 | 102 | mtspr SPRN_PMC6, r9 |
107 | BEGIN_FTR_SECTION | ||
108 | mtspr SPRN_PMC7, r10 | ||
109 | mtspr SPRN_PMC8, r11 | ||
110 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) | ||
111 | ld r3, HSTATE_MMCR(r13) | 103 | ld r3, HSTATE_MMCR(r13) |
112 | ld r4, HSTATE_MMCR + 8(r13) | 104 | ld r4, HSTATE_MMCR + 8(r13) |
113 | ld r5, HSTATE_MMCR + 16(r13) | 105 | ld r5, HSTATE_MMCR + 16(r13) |
@@ -153,11 +145,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) | |||
153 | 145 | ||
154 | cmpwi cr1, r12, BOOK3S_INTERRUPT_MACHINE_CHECK | 146 | cmpwi cr1, r12, BOOK3S_INTERRUPT_MACHINE_CHECK |
155 | cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL | 147 | cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL |
156 | BEGIN_FTR_SECTION | ||
157 | beq 11f | 148 | beq 11f |
158 | cmpwi cr2, r12, BOOK3S_INTERRUPT_HMI | 149 | cmpwi cr2, r12, BOOK3S_INTERRUPT_HMI |
159 | beq cr2, 14f /* HMI check */ | 150 | beq cr2, 14f /* HMI check */ |
160 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) | ||
161 | 151 | ||
162 | /* RFI into the highmem handler, or branch to interrupt handler */ | 152 | /* RFI into the highmem handler, or branch to interrupt handler */ |
163 | mfmsr r6 | 153 | mfmsr r6 |
@@ -166,7 +156,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) | |||
166 | mtmsrd r6, 1 /* Clear RI in MSR */ | 156 | mtmsrd r6, 1 /* Clear RI in MSR */ |
167 | mtsrr0 r8 | 157 | mtsrr0 r8 |
168 | mtsrr1 r7 | 158 | mtsrr1 r7 |
169 | beqa 0x500 /* external interrupt (PPC970) */ | ||
170 | beq cr1, 13f /* machine check */ | 159 | beq cr1, 13f /* machine check */ |
171 | RFI | 160 | RFI |
172 | 161 | ||
@@ -393,11 +382,8 @@ kvmppc_hv_entry: | |||
393 | slbia | 382 | slbia |
394 | ptesync | 383 | ptesync |
395 | 384 | ||
396 | BEGIN_FTR_SECTION | ||
397 | b 30f | ||
398 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) | ||
399 | /* | 385 | /* |
400 | * POWER7 host -> guest partition switch code. | 386 | * POWER7/POWER8 host -> guest partition switch code. |
401 | * We don't have to lock against concurrent tlbies, | 387 | * We don't have to lock against concurrent tlbies, |
402 | * but we do have to coordinate across hardware threads. | 388 | * but we do have to coordinate across hardware threads. |
403 | */ | 389 | */ |
@@ -505,97 +491,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) | |||
505 | cmpwi r3,512 /* 1 microsecond */ | 491 | cmpwi r3,512 /* 1 microsecond */ |
506 | li r12,BOOK3S_INTERRUPT_HV_DECREMENTER | 492 | li r12,BOOK3S_INTERRUPT_HV_DECREMENTER |
507 | blt hdec_soon | 493 | blt hdec_soon |
508 | b 31f | ||
509 | |||
510 | /* | ||
511 | * PPC970 host -> guest partition switch code. | ||
512 | * We have to lock against concurrent tlbies, | ||
513 | * using native_tlbie_lock to lock against host tlbies | ||
514 | * and kvm->arch.tlbie_lock to lock against guest tlbies. | ||
515 | * We also have to invalidate the TLB since its | ||
516 | * entries aren't tagged with the LPID. | ||
517 | */ | ||
518 | 30: ld r5,HSTATE_KVM_VCORE(r13) | ||
519 | ld r9,VCORE_KVM(r5) /* pointer to struct kvm */ | ||
520 | |||
521 | /* first take native_tlbie_lock */ | ||
522 | .section ".toc","aw" | ||
523 | toc_tlbie_lock: | ||
524 | .tc native_tlbie_lock[TC],native_tlbie_lock | ||
525 | .previous | ||
526 | ld r3,toc_tlbie_lock@toc(r2) | ||
527 | #ifdef __BIG_ENDIAN__ | ||
528 | lwz r8,PACA_LOCK_TOKEN(r13) | ||
529 | #else | ||
530 | lwz r8,PACAPACAINDEX(r13) | ||
531 | #endif | ||
532 | 24: lwarx r0,0,r3 | ||
533 | cmpwi r0,0 | ||
534 | bne 24b | ||
535 | stwcx. r8,0,r3 | ||
536 | bne 24b | ||
537 | isync | ||
538 | |||
539 | ld r5,HSTATE_KVM_VCORE(r13) | ||
540 | ld r7,VCORE_LPCR(r5) /* use vcore->lpcr to store HID4 */ | ||
541 | li r0,0x18f | ||
542 | rotldi r0,r0,HID4_LPID5_SH /* all lpid bits in HID4 = 1 */ | ||
543 | or r0,r7,r0 | ||
544 | ptesync | ||
545 | sync | ||
546 | mtspr SPRN_HID4,r0 /* switch to reserved LPID */ | ||
547 | isync | ||
548 | li r0,0 | ||
549 | stw r0,0(r3) /* drop native_tlbie_lock */ | ||
550 | |||
551 | /* invalidate the whole TLB */ | ||
552 | li r0,256 | ||
553 | mtctr r0 | ||
554 | li r6,0 | ||
555 | 25: tlbiel r6 | ||
556 | addi r6,r6,0x1000 | ||
557 | bdnz 25b | ||
558 | ptesync | ||
559 | 494 | ||
560 | /* Take the guest's tlbie_lock */ | ||
561 | addi r3,r9,KVM_TLBIE_LOCK | ||
562 | 24: lwarx r0,0,r3 | ||
563 | cmpwi r0,0 | ||
564 | bne 24b | ||
565 | stwcx. r8,0,r3 | ||
566 | bne 24b | ||
567 | isync | ||
568 | ld r6,KVM_SDR1(r9) | ||
569 | mtspr SPRN_SDR1,r6 /* switch to partition page table */ | ||
570 | |||
571 | /* Set up HID4 with the guest's LPID etc. */ | ||
572 | sync | ||
573 | mtspr SPRN_HID4,r7 | ||
574 | isync | ||
575 | |||
576 | /* drop the guest's tlbie_lock */ | ||
577 | li r0,0 | ||
578 | stw r0,0(r3) | ||
579 | |||
580 | /* Check if HDEC expires soon */ | ||
581 | mfspr r3,SPRN_HDEC | ||
582 | cmpwi r3,10 | ||
583 | li r12,BOOK3S_INTERRUPT_HV_DECREMENTER | ||
584 | blt hdec_soon | ||
585 | |||
586 | /* Enable HDEC interrupts */ | ||
587 | mfspr r0,SPRN_HID0 | ||
588 | li r3,1 | ||
589 | rldimi r0,r3, HID0_HDICE_SH, 64-HID0_HDICE_SH-1 | ||
590 | sync | ||
591 | mtspr SPRN_HID0,r0 | ||
592 | mfspr r0,SPRN_HID0 | ||
593 | mfspr r0,SPRN_HID0 | ||
594 | mfspr r0,SPRN_HID0 | ||
595 | mfspr r0,SPRN_HID0 | ||
596 | mfspr r0,SPRN_HID0 | ||
597 | mfspr r0,SPRN_HID0 | ||
598 | 31: | ||
599 | /* Do we have a guest vcpu to run? */ | 495 | /* Do we have a guest vcpu to run? */ |
600 | cmpdi r4, 0 | 496 | cmpdi r4, 0 |
601 | beq kvmppc_primary_no_guest | 497 | beq kvmppc_primary_no_guest |
@@ -625,7 +521,6 @@ kvmppc_got_guest: | |||
625 | stb r6, VCPU_VPA_DIRTY(r4) | 521 | stb r6, VCPU_VPA_DIRTY(r4) |
626 | 25: | 522 | 25: |
627 | 523 | ||
628 | BEGIN_FTR_SECTION | ||
629 | /* Save purr/spurr */ | 524 | /* Save purr/spurr */ |
630 | mfspr r5,SPRN_PURR | 525 | mfspr r5,SPRN_PURR |
631 | mfspr r6,SPRN_SPURR | 526 | mfspr r6,SPRN_SPURR |
@@ -635,7 +530,6 @@ BEGIN_FTR_SECTION | |||
635 | ld r8,VCPU_SPURR(r4) | 530 | ld r8,VCPU_SPURR(r4) |
636 | mtspr SPRN_PURR,r7 | 531 | mtspr SPRN_PURR,r7 |
637 | mtspr SPRN_SPURR,r8 | 532 | mtspr SPRN_SPURR,r8 |
638 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) | ||
639 | 533 | ||
640 | BEGIN_FTR_SECTION | 534 | BEGIN_FTR_SECTION |
641 | /* Set partition DABR */ | 535 | /* Set partition DABR */ |
@@ -644,9 +538,7 @@ BEGIN_FTR_SECTION | |||
644 | ld r6,VCPU_DABR(r4) | 538 | ld r6,VCPU_DABR(r4) |
645 | mtspr SPRN_DABRX,r5 | 539 | mtspr SPRN_DABRX,r5 |
646 | mtspr SPRN_DABR,r6 | 540 | mtspr SPRN_DABR,r6 |
647 | BEGIN_FTR_SECTION_NESTED(89) | ||
648 | isync | 541 | isync |
649 | END_FTR_SECTION_NESTED(CPU_FTR_ARCH_206, CPU_FTR_ARCH_206, 89) | ||
650 | END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) | 542 | END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) |
651 | 543 | ||
652 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 544 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
@@ -777,20 +669,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_PMAO_BUG) | |||
777 | lwz r7, VCPU_PMC + 12(r4) | 669 | lwz r7, VCPU_PMC + 12(r4) |
778 | lwz r8, VCPU_PMC + 16(r4) | 670 | lwz r8, VCPU_PMC + 16(r4) |
779 | lwz r9, VCPU_PMC + 20(r4) | 671 | lwz r9, VCPU_PMC + 20(r4) |
780 | BEGIN_FTR_SECTION | ||
781 | lwz r10, VCPU_PMC + 24(r4) | ||
782 | lwz r11, VCPU_PMC + 28(r4) | ||
783 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) | ||
784 | mtspr SPRN_PMC1, r3 | 672 | mtspr SPRN_PMC1, r3 |
785 | mtspr SPRN_PMC2, r5 | 673 | mtspr SPRN_PMC2, r5 |
786 | mtspr SPRN_PMC3, r6 | 674 | mtspr SPRN_PMC3, r6 |
787 | mtspr SPRN_PMC4, r7 | 675 | mtspr SPRN_PMC4, r7 |
788 | mtspr SPRN_PMC5, r8 | 676 | mtspr SPRN_PMC5, r8 |
789 | mtspr SPRN_PMC6, r9 | 677 | mtspr SPRN_PMC6, r9 |
790 | BEGIN_FTR_SECTION | ||
791 | mtspr SPRN_PMC7, r10 | ||
792 | mtspr SPRN_PMC8, r11 | ||
793 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) | ||
794 | ld r3, VCPU_MMCR(r4) | 678 | ld r3, VCPU_MMCR(r4) |
795 | ld r5, VCPU_MMCR + 8(r4) | 679 | ld r5, VCPU_MMCR + 8(r4) |
796 | ld r6, VCPU_MMCR + 16(r4) | 680 | ld r6, VCPU_MMCR + 16(r4) |
@@ -837,14 +721,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) | |||
837 | ld r30, VCPU_GPR(R30)(r4) | 721 | ld r30, VCPU_GPR(R30)(r4) |
838 | ld r31, VCPU_GPR(R31)(r4) | 722 | ld r31, VCPU_GPR(R31)(r4) |
839 | 723 | ||
840 | BEGIN_FTR_SECTION | ||
841 | /* Switch DSCR to guest value */ | 724 | /* Switch DSCR to guest value */ |
842 | ld r5, VCPU_DSCR(r4) | 725 | ld r5, VCPU_DSCR(r4) |
843 | mtspr SPRN_DSCR, r5 | 726 | mtspr SPRN_DSCR, r5 |
844 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) | ||
845 | 727 | ||
846 | BEGIN_FTR_SECTION | 728 | BEGIN_FTR_SECTION |
847 | /* Skip next section on POWER7 or PPC970 */ | 729 | /* Skip next section on POWER7 */ |
848 | b 8f | 730 | b 8f |
849 | END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) | 731 | END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) |
850 | /* Turn on TM so we can access TFHAR/TFIAR/TEXASR */ | 732 | /* Turn on TM so we can access TFHAR/TFIAR/TEXASR */ |
@@ -920,7 +802,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) | |||
920 | mtspr SPRN_DAR, r5 | 802 | mtspr SPRN_DAR, r5 |
921 | mtspr SPRN_DSISR, r6 | 803 | mtspr SPRN_DSISR, r6 |
922 | 804 | ||
923 | BEGIN_FTR_SECTION | ||
924 | /* Restore AMR and UAMOR, set AMOR to all 1s */ | 805 | /* Restore AMR and UAMOR, set AMOR to all 1s */ |
925 | ld r5,VCPU_AMR(r4) | 806 | ld r5,VCPU_AMR(r4) |
926 | ld r6,VCPU_UAMOR(r4) | 807 | ld r6,VCPU_UAMOR(r4) |
@@ -928,7 +809,6 @@ BEGIN_FTR_SECTION | |||
928 | mtspr SPRN_AMR,r5 | 809 | mtspr SPRN_AMR,r5 |
929 | mtspr SPRN_UAMOR,r6 | 810 | mtspr SPRN_UAMOR,r6 |
930 | mtspr SPRN_AMOR,r7 | 811 | mtspr SPRN_AMOR,r7 |
931 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) | ||
932 | 812 | ||
933 | /* Restore state of CTRL run bit; assume 1 on entry */ | 813 | /* Restore state of CTRL run bit; assume 1 on entry */ |
934 | lwz r5,VCPU_CTRL(r4) | 814 | lwz r5,VCPU_CTRL(r4) |
@@ -963,13 +843,11 @@ deliver_guest_interrupt: | |||
963 | rldicl r0, r0, 64 - BOOK3S_IRQPRIO_EXTERNAL_LEVEL, 63 | 843 | rldicl r0, r0, 64 - BOOK3S_IRQPRIO_EXTERNAL_LEVEL, 63 |
964 | cmpdi cr1, r0, 0 | 844 | cmpdi cr1, r0, 0 |
965 | andi. r8, r11, MSR_EE | 845 | andi. r8, r11, MSR_EE |
966 | BEGIN_FTR_SECTION | ||
967 | mfspr r8, SPRN_LPCR | 846 | mfspr r8, SPRN_LPCR |
968 | /* Insert EXTERNAL_LEVEL bit into LPCR at the MER bit position */ | 847 | /* Insert EXTERNAL_LEVEL bit into LPCR at the MER bit position */ |
969 | rldimi r8, r0, LPCR_MER_SH, 63 - LPCR_MER_SH | 848 | rldimi r8, r0, LPCR_MER_SH, 63 - LPCR_MER_SH |
970 | mtspr SPRN_LPCR, r8 | 849 | mtspr SPRN_LPCR, r8 |
971 | isync | 850 | isync |
972 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) | ||
973 | beq 5f | 851 | beq 5f |
974 | li r0, BOOK3S_INTERRUPT_EXTERNAL | 852 | li r0, BOOK3S_INTERRUPT_EXTERNAL |
975 | bne cr1, 12f | 853 | bne cr1, 12f |
@@ -1124,15 +1002,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) | |||
1124 | 1002 | ||
1125 | stw r12,VCPU_TRAP(r9) | 1003 | stw r12,VCPU_TRAP(r9) |
1126 | 1004 | ||
1127 | /* Save HEIR (HV emulation assist reg) in last_inst | 1005 | /* Save HEIR (HV emulation assist reg) in emul_inst |
1128 | if this is an HEI (HV emulation interrupt, e40) */ | 1006 | if this is an HEI (HV emulation interrupt, e40) */ |
1129 | li r3,KVM_INST_FETCH_FAILED | 1007 | li r3,KVM_INST_FETCH_FAILED |
1130 | BEGIN_FTR_SECTION | ||
1131 | cmpwi r12,BOOK3S_INTERRUPT_H_EMUL_ASSIST | 1008 | cmpwi r12,BOOK3S_INTERRUPT_H_EMUL_ASSIST |
1132 | bne 11f | 1009 | bne 11f |
1133 | mfspr r3,SPRN_HEIR | 1010 | mfspr r3,SPRN_HEIR |
1134 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) | 1011 | 11: stw r3,VCPU_HEIR(r9) |
1135 | 11: stw r3,VCPU_LAST_INST(r9) | ||
1136 | 1012 | ||
1137 | /* these are volatile across C function calls */ | 1013 | /* these are volatile across C function calls */ |
1138 | mfctr r3 | 1014 | mfctr r3 |
@@ -1140,13 +1016,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) | |||
1140 | std r3, VCPU_CTR(r9) | 1016 | std r3, VCPU_CTR(r9) |
1141 | stw r4, VCPU_XER(r9) | 1017 | stw r4, VCPU_XER(r9) |
1142 | 1018 | ||
1143 | BEGIN_FTR_SECTION | ||
1144 | /* If this is a page table miss then see if it's theirs or ours */ | 1019 | /* If this is a page table miss then see if it's theirs or ours */ |
1145 | cmpwi r12, BOOK3S_INTERRUPT_H_DATA_STORAGE | 1020 | cmpwi r12, BOOK3S_INTERRUPT_H_DATA_STORAGE |
1146 | beq kvmppc_hdsi | 1021 | beq kvmppc_hdsi |
1147 | cmpwi r12, BOOK3S_INTERRUPT_H_INST_STORAGE | 1022 | cmpwi r12, BOOK3S_INTERRUPT_H_INST_STORAGE |
1148 | beq kvmppc_hisi | 1023 | beq kvmppc_hisi |
1149 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) | ||
1150 | 1024 | ||
1151 | /* See if this is a leftover HDEC interrupt */ | 1025 | /* See if this is a leftover HDEC interrupt */ |
1152 | cmpwi r12,BOOK3S_INTERRUPT_HV_DECREMENTER | 1026 | cmpwi r12,BOOK3S_INTERRUPT_HV_DECREMENTER |
@@ -1159,11 +1033,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) | |||
1159 | cmpwi r12,BOOK3S_INTERRUPT_SYSCALL | 1033 | cmpwi r12,BOOK3S_INTERRUPT_SYSCALL |
1160 | beq hcall_try_real_mode | 1034 | beq hcall_try_real_mode |
1161 | 1035 | ||
1162 | /* Only handle external interrupts here on arch 206 and later */ | ||
1163 | BEGIN_FTR_SECTION | ||
1164 | b ext_interrupt_to_host | ||
1165 | END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206) | ||
1166 | |||
1167 | /* External interrupt ? */ | 1036 | /* External interrupt ? */ |
1168 | cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL | 1037 | cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL |
1169 | bne+ ext_interrupt_to_host | 1038 | bne+ ext_interrupt_to_host |
@@ -1193,11 +1062,9 @@ guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */ | |||
1193 | mfdsisr r7 | 1062 | mfdsisr r7 |
1194 | std r6, VCPU_DAR(r9) | 1063 | std r6, VCPU_DAR(r9) |
1195 | stw r7, VCPU_DSISR(r9) | 1064 | stw r7, VCPU_DSISR(r9) |
1196 | BEGIN_FTR_SECTION | ||
1197 | /* don't overwrite fault_dar/fault_dsisr if HDSI */ | 1065 | /* don't overwrite fault_dar/fault_dsisr if HDSI */ |
1198 | cmpwi r12,BOOK3S_INTERRUPT_H_DATA_STORAGE | 1066 | cmpwi r12,BOOK3S_INTERRUPT_H_DATA_STORAGE |
1199 | beq 6f | 1067 | beq 6f |
1200 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) | ||
1201 | std r6, VCPU_FAULT_DAR(r9) | 1068 | std r6, VCPU_FAULT_DAR(r9) |
1202 | stw r7, VCPU_FAULT_DSISR(r9) | 1069 | stw r7, VCPU_FAULT_DSISR(r9) |
1203 | 1070 | ||
@@ -1236,7 +1103,6 @@ mc_cont: | |||
1236 | /* | 1103 | /* |
1237 | * Save the guest PURR/SPURR | 1104 | * Save the guest PURR/SPURR |
1238 | */ | 1105 | */ |
1239 | BEGIN_FTR_SECTION | ||
1240 | mfspr r5,SPRN_PURR | 1106 | mfspr r5,SPRN_PURR |
1241 | mfspr r6,SPRN_SPURR | 1107 | mfspr r6,SPRN_SPURR |
1242 | ld r7,VCPU_PURR(r9) | 1108 | ld r7,VCPU_PURR(r9) |
@@ -1256,7 +1122,6 @@ BEGIN_FTR_SECTION | |||
1256 | add r4,r4,r6 | 1122 | add r4,r4,r6 |
1257 | mtspr SPRN_PURR,r3 | 1123 | mtspr SPRN_PURR,r3 |
1258 | mtspr SPRN_SPURR,r4 | 1124 | mtspr SPRN_SPURR,r4 |
1259 | END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_201) | ||
1260 | 1125 | ||
1261 | /* Save DEC */ | 1126 | /* Save DEC */ |
1262 | mfspr r5,SPRN_DEC | 1127 | mfspr r5,SPRN_DEC |
@@ -1306,22 +1171,18 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) | |||
1306 | 8: | 1171 | 8: |
1307 | 1172 | ||
1308 | /* Save and reset AMR and UAMOR before turning on the MMU */ | 1173 | /* Save and reset AMR and UAMOR before turning on the MMU */ |
1309 | BEGIN_FTR_SECTION | ||
1310 | mfspr r5,SPRN_AMR | 1174 | mfspr r5,SPRN_AMR |
1311 | mfspr r6,SPRN_UAMOR | 1175 | mfspr r6,SPRN_UAMOR |
1312 | std r5,VCPU_AMR(r9) | 1176 | std r5,VCPU_AMR(r9) |
1313 | std r6,VCPU_UAMOR(r9) | 1177 | std r6,VCPU_UAMOR(r9) |
1314 | li r6,0 | 1178 | li r6,0 |
1315 | mtspr SPRN_AMR,r6 | 1179 | mtspr SPRN_AMR,r6 |
1316 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) | ||
1317 | 1180 | ||
1318 | /* Switch DSCR back to host value */ | 1181 | /* Switch DSCR back to host value */ |
1319 | BEGIN_FTR_SECTION | ||
1320 | mfspr r8, SPRN_DSCR | 1182 | mfspr r8, SPRN_DSCR |
1321 | ld r7, HSTATE_DSCR(r13) | 1183 | ld r7, HSTATE_DSCR(r13) |
1322 | std r8, VCPU_DSCR(r9) | 1184 | std r8, VCPU_DSCR(r9) |
1323 | mtspr SPRN_DSCR, r7 | 1185 | mtspr SPRN_DSCR, r7 |
1324 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) | ||
1325 | 1186 | ||
1326 | /* Save non-volatile GPRs */ | 1187 | /* Save non-volatile GPRs */ |
1327 | std r14, VCPU_GPR(R14)(r9) | 1188 | std r14, VCPU_GPR(R14)(r9) |
@@ -1503,11 +1364,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) | |||
1503 | mfspr r4, SPRN_MMCR0 /* save MMCR0 */ | 1364 | mfspr r4, SPRN_MMCR0 /* save MMCR0 */ |
1504 | mtspr SPRN_MMCR0, r3 /* freeze all counters, disable ints */ | 1365 | mtspr SPRN_MMCR0, r3 /* freeze all counters, disable ints */ |
1505 | mfspr r6, SPRN_MMCRA | 1366 | mfspr r6, SPRN_MMCRA |
1506 | BEGIN_FTR_SECTION | 1367 | /* Clear MMCRA in order to disable SDAR updates */ |
1507 | /* On P7, clear MMCRA in order to disable SDAR updates */ | ||
1508 | li r7, 0 | 1368 | li r7, 0 |
1509 | mtspr SPRN_MMCRA, r7 | 1369 | mtspr SPRN_MMCRA, r7 |
1510 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) | ||
1511 | isync | 1370 | isync |
1512 | beq 21f /* if no VPA, save PMU stuff anyway */ | 1371 | beq 21f /* if no VPA, save PMU stuff anyway */ |
1513 | lbz r7, LPPACA_PMCINUSE(r8) | 1372 | lbz r7, LPPACA_PMCINUSE(r8) |
@@ -1532,10 +1391,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) | |||
1532 | mfspr r6, SPRN_PMC4 | 1391 | mfspr r6, SPRN_PMC4 |
1533 | mfspr r7, SPRN_PMC5 | 1392 | mfspr r7, SPRN_PMC5 |
1534 | mfspr r8, SPRN_PMC6 | 1393 | mfspr r8, SPRN_PMC6 |
1535 | BEGIN_FTR_SECTION | ||
1536 | mfspr r10, SPRN_PMC7 | ||
1537 | mfspr r11, SPRN_PMC8 | ||
1538 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) | ||
1539 | stw r3, VCPU_PMC(r9) | 1394 | stw r3, VCPU_PMC(r9) |
1540 | stw r4, VCPU_PMC + 4(r9) | 1395 | stw r4, VCPU_PMC + 4(r9) |
1541 | stw r5, VCPU_PMC + 8(r9) | 1396 | stw r5, VCPU_PMC + 8(r9) |
@@ -1543,10 +1398,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) | |||
1543 | stw r7, VCPU_PMC + 16(r9) | 1398 | stw r7, VCPU_PMC + 16(r9) |
1544 | stw r8, VCPU_PMC + 20(r9) | 1399 | stw r8, VCPU_PMC + 20(r9) |
1545 | BEGIN_FTR_SECTION | 1400 | BEGIN_FTR_SECTION |
1546 | stw r10, VCPU_PMC + 24(r9) | ||
1547 | stw r11, VCPU_PMC + 28(r9) | ||
1548 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) | ||
1549 | BEGIN_FTR_SECTION | ||
1550 | mfspr r5, SPRN_SIER | 1401 | mfspr r5, SPRN_SIER |
1551 | mfspr r6, SPRN_SPMC1 | 1402 | mfspr r6, SPRN_SPMC1 |
1552 | mfspr r7, SPRN_SPMC2 | 1403 | mfspr r7, SPRN_SPMC2 |
@@ -1566,11 +1417,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) | |||
1566 | ptesync | 1417 | ptesync |
1567 | 1418 | ||
1568 | hdec_soon: /* r12 = trap, r13 = paca */ | 1419 | hdec_soon: /* r12 = trap, r13 = paca */ |
1569 | BEGIN_FTR_SECTION | ||
1570 | b 32f | ||
1571 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) | ||
1572 | /* | 1420 | /* |
1573 | * POWER7 guest -> host partition switch code. | 1421 | * POWER7/POWER8 guest -> host partition switch code. |
1574 | * We don't have to lock against tlbies but we do | 1422 | * We don't have to lock against tlbies but we do |
1575 | * have to coordinate the hardware threads. | 1423 | * have to coordinate the hardware threads. |
1576 | */ | 1424 | */ |
@@ -1698,87 +1546,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) | |||
1698 | 16: ld r8,KVM_HOST_LPCR(r4) | 1546 | 16: ld r8,KVM_HOST_LPCR(r4) |
1699 | mtspr SPRN_LPCR,r8 | 1547 | mtspr SPRN_LPCR,r8 |
1700 | isync | 1548 | isync |
1701 | b 33f | ||
1702 | |||
1703 | /* | ||
1704 | * PPC970 guest -> host partition switch code. | ||
1705 | * We have to lock against concurrent tlbies, and | ||
1706 | * we have to flush the whole TLB. | ||
1707 | */ | ||
1708 | 32: ld r5,HSTATE_KVM_VCORE(r13) | ||
1709 | ld r4,VCORE_KVM(r5) /* pointer to struct kvm */ | ||
1710 | |||
1711 | /* Take the guest's tlbie_lock */ | ||
1712 | #ifdef __BIG_ENDIAN__ | ||
1713 | lwz r8,PACA_LOCK_TOKEN(r13) | ||
1714 | #else | ||
1715 | lwz r8,PACAPACAINDEX(r13) | ||
1716 | #endif | ||
1717 | addi r3,r4,KVM_TLBIE_LOCK | ||
1718 | 24: lwarx r0,0,r3 | ||
1719 | cmpwi r0,0 | ||
1720 | bne 24b | ||
1721 | stwcx. r8,0,r3 | ||
1722 | bne 24b | ||
1723 | isync | ||
1724 | |||
1725 | ld r7,KVM_HOST_LPCR(r4) /* use kvm->arch.host_lpcr for HID4 */ | ||
1726 | li r0,0x18f | ||
1727 | rotldi r0,r0,HID4_LPID5_SH /* all lpid bits in HID4 = 1 */ | ||
1728 | or r0,r7,r0 | ||
1729 | ptesync | ||
1730 | sync | ||
1731 | mtspr SPRN_HID4,r0 /* switch to reserved LPID */ | ||
1732 | isync | ||
1733 | li r0,0 | ||
1734 | stw r0,0(r3) /* drop guest tlbie_lock */ | ||
1735 | |||
1736 | /* invalidate the whole TLB */ | ||
1737 | li r0,256 | ||
1738 | mtctr r0 | ||
1739 | li r6,0 | ||
1740 | 25: tlbiel r6 | ||
1741 | addi r6,r6,0x1000 | ||
1742 | bdnz 25b | ||
1743 | ptesync | ||
1744 | |||
1745 | /* take native_tlbie_lock */ | ||
1746 | ld r3,toc_tlbie_lock@toc(2) | ||
1747 | 24: lwarx r0,0,r3 | ||
1748 | cmpwi r0,0 | ||
1749 | bne 24b | ||
1750 | stwcx. r8,0,r3 | ||
1751 | bne 24b | ||
1752 | isync | ||
1753 | |||
1754 | ld r6,KVM_HOST_SDR1(r4) | ||
1755 | mtspr SPRN_SDR1,r6 /* switch to host page table */ | ||
1756 | |||
1757 | /* Set up host HID4 value */ | ||
1758 | sync | ||
1759 | mtspr SPRN_HID4,r7 | ||
1760 | isync | ||
1761 | li r0,0 | ||
1762 | stw r0,0(r3) /* drop native_tlbie_lock */ | ||
1763 | |||
1764 | lis r8,0x7fff /* MAX_INT@h */ | ||
1765 | mtspr SPRN_HDEC,r8 | ||
1766 | |||
1767 | /* Disable HDEC interrupts */ | ||
1768 | mfspr r0,SPRN_HID0 | ||
1769 | li r3,0 | ||
1770 | rldimi r0,r3, HID0_HDICE_SH, 64-HID0_HDICE_SH-1 | ||
1771 | sync | ||
1772 | mtspr SPRN_HID0,r0 | ||
1773 | mfspr r0,SPRN_HID0 | ||
1774 | mfspr r0,SPRN_HID0 | ||
1775 | mfspr r0,SPRN_HID0 | ||
1776 | mfspr r0,SPRN_HID0 | ||
1777 | mfspr r0,SPRN_HID0 | ||
1778 | mfspr r0,SPRN_HID0 | ||
1779 | 1549 | ||
1780 | /* load host SLB entries */ | 1550 | /* load host SLB entries */ |
1781 | 33: ld r8,PACA_SLBSHADOWPTR(r13) | 1551 | ld r8,PACA_SLBSHADOWPTR(r13) |
1782 | 1552 | ||
1783 | .rept SLB_NUM_BOLTED | 1553 | .rept SLB_NUM_BOLTED |
1784 | li r3, SLBSHADOW_SAVEAREA | 1554 | li r3, SLBSHADOW_SAVEAREA |
@@ -2047,7 +1817,7 @@ hcall_real_table: | |||
2047 | .long 0 /* 0xd8 */ | 1817 | .long 0 /* 0xd8 */ |
2048 | .long 0 /* 0xdc */ | 1818 | .long 0 /* 0xdc */ |
2049 | .long DOTSYM(kvmppc_h_cede) - hcall_real_table | 1819 | .long DOTSYM(kvmppc_h_cede) - hcall_real_table |
2050 | .long 0 /* 0xe4 */ | 1820 | .long DOTSYM(kvmppc_rm_h_confer) - hcall_real_table |
2051 | .long 0 /* 0xe8 */ | 1821 | .long 0 /* 0xe8 */ |
2052 | .long 0 /* 0xec */ | 1822 | .long 0 /* 0xec */ |
2053 | .long 0 /* 0xf0 */ | 1823 | .long 0 /* 0xf0 */ |
@@ -2126,9 +1896,6 @@ _GLOBAL(kvmppc_h_cede) | |||
2126 | stw r0,VCPU_TRAP(r3) | 1896 | stw r0,VCPU_TRAP(r3) |
2127 | li r0,H_SUCCESS | 1897 | li r0,H_SUCCESS |
2128 | std r0,VCPU_GPR(R3)(r3) | 1898 | std r0,VCPU_GPR(R3)(r3) |
2129 | BEGIN_FTR_SECTION | ||
2130 | b kvm_cede_exit /* just send it up to host on 970 */ | ||
2131 | END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206) | ||
2132 | 1899 | ||
2133 | /* | 1900 | /* |
2134 | * Set our bit in the bitmask of napping threads unless all the | 1901 | * Set our bit in the bitmask of napping threads unless all the |
@@ -2455,7 +2222,6 @@ BEGIN_FTR_SECTION | |||
2455 | END_FTR_SECTION_IFSET(CPU_FTR_VSX) | 2222 | END_FTR_SECTION_IFSET(CPU_FTR_VSX) |
2456 | #endif | 2223 | #endif |
2457 | mtmsrd r8 | 2224 | mtmsrd r8 |
2458 | isync | ||
2459 | addi r3,r3,VCPU_FPRS | 2225 | addi r3,r3,VCPU_FPRS |
2460 | bl store_fp_state | 2226 | bl store_fp_state |
2461 | #ifdef CONFIG_ALTIVEC | 2227 | #ifdef CONFIG_ALTIVEC |
@@ -2491,7 +2257,6 @@ BEGIN_FTR_SECTION | |||
2491 | END_FTR_SECTION_IFSET(CPU_FTR_VSX) | 2257 | END_FTR_SECTION_IFSET(CPU_FTR_VSX) |
2492 | #endif | 2258 | #endif |
2493 | mtmsrd r8 | 2259 | mtmsrd r8 |
2494 | isync | ||
2495 | addi r3,r4,VCPU_FPRS | 2260 | addi r3,r4,VCPU_FPRS |
2496 | bl load_fp_state | 2261 | bl load_fp_state |
2497 | #ifdef CONFIG_ALTIVEC | 2262 | #ifdef CONFIG_ALTIVEC |
diff --git a/arch/powerpc/kvm/book3s_paired_singles.c b/arch/powerpc/kvm/book3s_paired_singles.c index bfb8035314e3..bd6ab1672ae6 100644 --- a/arch/powerpc/kvm/book3s_paired_singles.c +++ b/arch/powerpc/kvm/book3s_paired_singles.c | |||
@@ -352,14 +352,6 @@ static inline u32 inst_get_field(u32 inst, int msb, int lsb) | |||
352 | return kvmppc_get_field(inst, msb + 32, lsb + 32); | 352 | return kvmppc_get_field(inst, msb + 32, lsb + 32); |
353 | } | 353 | } |
354 | 354 | ||
355 | /* | ||
356 | * Replaces inst bits with ordering according to spec. | ||
357 | */ | ||
358 | static inline u32 inst_set_field(u32 inst, int msb, int lsb, int value) | ||
359 | { | ||
360 | return kvmppc_set_field(inst, msb + 32, lsb + 32, value); | ||
361 | } | ||
362 | |||
363 | bool kvmppc_inst_is_paired_single(struct kvm_vcpu *vcpu, u32 inst) | 355 | bool kvmppc_inst_is_paired_single(struct kvm_vcpu *vcpu, u32 inst) |
364 | { | 356 | { |
365 | if (!(vcpu->arch.hflags & BOOK3S_HFLAG_PAIRED_SINGLE)) | 357 | if (!(vcpu->arch.hflags & BOOK3S_HFLAG_PAIRED_SINGLE)) |
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index cf2eb16846d1..f57383941d03 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c | |||
@@ -644,11 +644,6 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
644 | return r; | 644 | return r; |
645 | } | 645 | } |
646 | 646 | ||
647 | static inline int get_fpr_index(int i) | ||
648 | { | ||
649 | return i * TS_FPRWIDTH; | ||
650 | } | ||
651 | |||
652 | /* Give up external provider (FPU, Altivec, VSX) */ | 647 | /* Give up external provider (FPU, Altivec, VSX) */ |
653 | void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr) | 648 | void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr) |
654 | { | 649 | { |
diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c index eaeb78047fb8..807351f76f84 100644 --- a/arch/powerpc/kvm/book3s_xics.c +++ b/arch/powerpc/kvm/book3s_xics.c | |||
@@ -613,10 +613,25 @@ static noinline int kvmppc_h_ipi(struct kvm_vcpu *vcpu, unsigned long server, | |||
613 | * there might be a previously-rejected interrupt needing | 613 | * there might be a previously-rejected interrupt needing |
614 | * to be resent. | 614 | * to be resent. |
615 | * | 615 | * |
616 | * ICP state: Check_IPI | ||
617 | * | ||
616 | * If the CPPR is less favored, then we might be replacing | 618 | * If the CPPR is less favored, then we might be replacing |
617 | * an interrupt, and thus need to possibly reject it as in | 619 | * an interrupt, and thus need to possibly reject it. |
618 | * | 620 | * |
619 | * ICP state: Check_IPI | 621 | * ICP State: IPI |
622 | * | ||
623 | * Besides rejecting any pending interrupts, we also | ||
624 | * update XISR and pending_pri to mark IPI as pending. | ||
625 | * | ||
626 | * PAPR does not describe this state, but if the MFRR is being | ||
627 | * made less favored than its earlier value, there might be | ||
628 | * a previously-rejected interrupt needing to be resent. | ||
629 | * Ideally, we would want to resend only if | ||
630 | * prio(pending_interrupt) < mfrr && | ||
631 | * prio(pending_interrupt) < cppr | ||
632 | * where pending interrupt is the one that was rejected. But | ||
633 | * we don't have that state, so we simply trigger a resend | ||
634 | * whenever the MFRR is made less favored. | ||
620 | */ | 635 | */ |
621 | do { | 636 | do { |
622 | old_state = new_state = ACCESS_ONCE(icp->state); | 637 | old_state = new_state = ACCESS_ONCE(icp->state); |
@@ -629,13 +644,14 @@ static noinline int kvmppc_h_ipi(struct kvm_vcpu *vcpu, unsigned long server, | |||
629 | resend = false; | 644 | resend = false; |
630 | if (mfrr < new_state.cppr) { | 645 | if (mfrr < new_state.cppr) { |
631 | /* Reject a pending interrupt if not an IPI */ | 646 | /* Reject a pending interrupt if not an IPI */ |
632 | if (mfrr <= new_state.pending_pri) | 647 | if (mfrr <= new_state.pending_pri) { |
633 | reject = new_state.xisr; | 648 | reject = new_state.xisr; |
634 | new_state.pending_pri = mfrr; | 649 | new_state.pending_pri = mfrr; |
635 | new_state.xisr = XICS_IPI; | 650 | new_state.xisr = XICS_IPI; |
651 | } | ||
636 | } | 652 | } |
637 | 653 | ||
638 | if (mfrr > old_state.mfrr && mfrr > new_state.cppr) { | 654 | if (mfrr > old_state.mfrr) { |
639 | resend = new_state.need_resend; | 655 | resend = new_state.need_resend; |
640 | new_state.need_resend = 0; | 656 | new_state.need_resend = 0; |
641 | } | 657 | } |
@@ -789,7 +805,7 @@ static noinline int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall) | |||
789 | if (icp->rm_action & XICS_RM_KICK_VCPU) | 805 | if (icp->rm_action & XICS_RM_KICK_VCPU) |
790 | kvmppc_fast_vcpu_kick(icp->rm_kick_target); | 806 | kvmppc_fast_vcpu_kick(icp->rm_kick_target); |
791 | if (icp->rm_action & XICS_RM_CHECK_RESEND) | 807 | if (icp->rm_action & XICS_RM_CHECK_RESEND) |
792 | icp_check_resend(xics, icp); | 808 | icp_check_resend(xics, icp->rm_resend_icp); |
793 | if (icp->rm_action & XICS_RM_REJECT) | 809 | if (icp->rm_action & XICS_RM_REJECT) |
794 | icp_deliver_irq(xics, icp, icp->rm_reject); | 810 | icp_deliver_irq(xics, icp, icp->rm_reject); |
795 | if (icp->rm_action & XICS_RM_NOTIFY_EOI) | 811 | if (icp->rm_action & XICS_RM_NOTIFY_EOI) |
diff --git a/arch/powerpc/kvm/book3s_xics.h b/arch/powerpc/kvm/book3s_xics.h index e8aaa7a3f209..73f0f2723c07 100644 --- a/arch/powerpc/kvm/book3s_xics.h +++ b/arch/powerpc/kvm/book3s_xics.h | |||
@@ -74,6 +74,7 @@ struct kvmppc_icp { | |||
74 | #define XICS_RM_NOTIFY_EOI 0x8 | 74 | #define XICS_RM_NOTIFY_EOI 0x8 |
75 | u32 rm_action; | 75 | u32 rm_action; |
76 | struct kvm_vcpu *rm_kick_target; | 76 | struct kvm_vcpu *rm_kick_target; |
77 | struct kvmppc_icp *rm_resend_icp; | ||
77 | u32 rm_reject; | 78 | u32 rm_reject; |
78 | u32 rm_eoied_irq; | 79 | u32 rm_eoied_irq; |
79 | 80 | ||
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c index e1cb5881bd56..b29ce752c7d6 100644 --- a/arch/powerpc/kvm/e500.c +++ b/arch/powerpc/kvm/e500.c | |||
@@ -299,14 +299,6 @@ void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr) | |||
299 | kvmppc_e500_recalc_shadow_pid(to_e500(vcpu)); | 299 | kvmppc_e500_recalc_shadow_pid(to_e500(vcpu)); |
300 | } | 300 | } |
301 | 301 | ||
302 | void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu) | ||
303 | { | ||
304 | } | ||
305 | |||
306 | void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu) | ||
307 | { | ||
308 | } | ||
309 | |||
310 | static void kvmppc_core_vcpu_load_e500(struct kvm_vcpu *vcpu, int cpu) | 302 | static void kvmppc_core_vcpu_load_e500(struct kvm_vcpu *vcpu, int cpu) |
311 | { | 303 | { |
312 | kvmppc_booke_vcpu_load(vcpu, cpu); | 304 | kvmppc_booke_vcpu_load(vcpu, cpu); |
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index c1f8f53cd312..c45eaab752b0 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -527,18 +527,12 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) | |||
527 | r = 0; | 527 | r = 0; |
528 | break; | 528 | break; |
529 | case KVM_CAP_PPC_RMA: | 529 | case KVM_CAP_PPC_RMA: |
530 | r = hv_enabled; | 530 | r = 0; |
531 | /* PPC970 requires an RMA */ | ||
532 | if (r && cpu_has_feature(CPU_FTR_ARCH_201)) | ||
533 | r = 2; | ||
534 | break; | 531 | break; |
535 | #endif | 532 | #endif |
536 | case KVM_CAP_SYNC_MMU: | 533 | case KVM_CAP_SYNC_MMU: |
537 | #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE | 534 | #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE |
538 | if (hv_enabled) | 535 | r = hv_enabled; |
539 | r = cpu_has_feature(CPU_FTR_ARCH_206) ? 1 : 0; | ||
540 | else | ||
541 | r = 0; | ||
542 | #elif defined(KVM_ARCH_WANT_MMU_NOTIFIER) | 536 | #elif defined(KVM_ARCH_WANT_MMU_NOTIFIER) |
543 | r = 1; | 537 | r = 1; |
544 | #else | 538 | #else |
diff --git a/arch/powerpc/kvm/trace_book3s.h b/arch/powerpc/kvm/trace_book3s.h new file mode 100644 index 000000000000..f647ce0f428b --- /dev/null +++ b/arch/powerpc/kvm/trace_book3s.h | |||
@@ -0,0 +1,32 @@ | |||
1 | #if !defined(_TRACE_KVM_BOOK3S_H) | ||
2 | #define _TRACE_KVM_BOOK3S_H | ||
3 | |||
4 | /* | ||
5 | * Common defines used by the trace macros in trace_pr.h and trace_hv.h | ||
6 | */ | ||
7 | |||
8 | #define kvm_trace_symbol_exit \ | ||
9 | {0x100, "SYSTEM_RESET"}, \ | ||
10 | {0x200, "MACHINE_CHECK"}, \ | ||
11 | {0x300, "DATA_STORAGE"}, \ | ||
12 | {0x380, "DATA_SEGMENT"}, \ | ||
13 | {0x400, "INST_STORAGE"}, \ | ||
14 | {0x480, "INST_SEGMENT"}, \ | ||
15 | {0x500, "EXTERNAL"}, \ | ||
16 | {0x501, "EXTERNAL_LEVEL"}, \ | ||
17 | {0x502, "EXTERNAL_HV"}, \ | ||
18 | {0x600, "ALIGNMENT"}, \ | ||
19 | {0x700, "PROGRAM"}, \ | ||
20 | {0x800, "FP_UNAVAIL"}, \ | ||
21 | {0x900, "DECREMENTER"}, \ | ||
22 | {0x980, "HV_DECREMENTER"}, \ | ||
23 | {0xc00, "SYSCALL"}, \ | ||
24 | {0xd00, "TRACE"}, \ | ||
25 | {0xe00, "H_DATA_STORAGE"}, \ | ||
26 | {0xe20, "H_INST_STORAGE"}, \ | ||
27 | {0xe40, "H_EMUL_ASSIST"}, \ | ||
28 | {0xf00, "PERFMON"}, \ | ||
29 | {0xf20, "ALTIVEC"}, \ | ||
30 | {0xf40, "VSX"} | ||
31 | |||
32 | #endif | ||
diff --git a/arch/powerpc/kvm/trace_booke.h b/arch/powerpc/kvm/trace_booke.h index f7537cf26ce7..7ec534d1db9f 100644 --- a/arch/powerpc/kvm/trace_booke.h +++ b/arch/powerpc/kvm/trace_booke.h | |||
@@ -151,6 +151,47 @@ TRACE_EVENT(kvm_booke206_ref_release, | |||
151 | __entry->pfn, __entry->flags) | 151 | __entry->pfn, __entry->flags) |
152 | ); | 152 | ); |
153 | 153 | ||
154 | #ifdef CONFIG_SPE_POSSIBLE | ||
155 | #define kvm_trace_symbol_irqprio_spe \ | ||
156 | {BOOKE_IRQPRIO_SPE_UNAVAIL, "SPE_UNAVAIL"}, \ | ||
157 | {BOOKE_IRQPRIO_SPE_FP_DATA, "SPE_FP_DATA"}, \ | ||
158 | {BOOKE_IRQPRIO_SPE_FP_ROUND, "SPE_FP_ROUND"}, | ||
159 | #else | ||
160 | #define kvm_trace_symbol_irqprio_spe | ||
161 | #endif | ||
162 | |||
163 | #ifdef CONFIG_PPC_E500MC | ||
164 | #define kvm_trace_symbol_irqprio_e500mc \ | ||
165 | {BOOKE_IRQPRIO_ALTIVEC_UNAVAIL, "ALTIVEC_UNAVAIL"}, \ | ||
166 | {BOOKE_IRQPRIO_ALTIVEC_ASSIST, "ALTIVEC_ASSIST"}, | ||
167 | #else | ||
168 | #define kvm_trace_symbol_irqprio_e500mc | ||
169 | #endif | ||
170 | |||
171 | #define kvm_trace_symbol_irqprio \ | ||
172 | kvm_trace_symbol_irqprio_spe \ | ||
173 | kvm_trace_symbol_irqprio_e500mc \ | ||
174 | {BOOKE_IRQPRIO_DATA_STORAGE, "DATA_STORAGE"}, \ | ||
175 | {BOOKE_IRQPRIO_INST_STORAGE, "INST_STORAGE"}, \ | ||
176 | {BOOKE_IRQPRIO_ALIGNMENT, "ALIGNMENT"}, \ | ||
177 | {BOOKE_IRQPRIO_PROGRAM, "PROGRAM"}, \ | ||
178 | {BOOKE_IRQPRIO_FP_UNAVAIL, "FP_UNAVAIL"}, \ | ||
179 | {BOOKE_IRQPRIO_SYSCALL, "SYSCALL"}, \ | ||
180 | {BOOKE_IRQPRIO_AP_UNAVAIL, "AP_UNAVAIL"}, \ | ||
181 | {BOOKE_IRQPRIO_DTLB_MISS, "DTLB_MISS"}, \ | ||
182 | {BOOKE_IRQPRIO_ITLB_MISS, "ITLB_MISS"}, \ | ||
183 | {BOOKE_IRQPRIO_MACHINE_CHECK, "MACHINE_CHECK"}, \ | ||
184 | {BOOKE_IRQPRIO_DEBUG, "DEBUG"}, \ | ||
185 | {BOOKE_IRQPRIO_CRITICAL, "CRITICAL"}, \ | ||
186 | {BOOKE_IRQPRIO_WATCHDOG, "WATCHDOG"}, \ | ||
187 | {BOOKE_IRQPRIO_EXTERNAL, "EXTERNAL"}, \ | ||
188 | {BOOKE_IRQPRIO_FIT, "FIT"}, \ | ||
189 | {BOOKE_IRQPRIO_DECREMENTER, "DECREMENTER"}, \ | ||
190 | {BOOKE_IRQPRIO_PERFORMANCE_MONITOR, "PERFORMANCE_MONITOR"}, \ | ||
191 | {BOOKE_IRQPRIO_EXTERNAL_LEVEL, "EXTERNAL_LEVEL"}, \ | ||
192 | {BOOKE_IRQPRIO_DBELL, "DBELL"}, \ | ||
193 | {BOOKE_IRQPRIO_DBELL_CRIT, "DBELL_CRIT"} \ | ||
194 | |||
154 | TRACE_EVENT(kvm_booke_queue_irqprio, | 195 | TRACE_EVENT(kvm_booke_queue_irqprio, |
155 | TP_PROTO(struct kvm_vcpu *vcpu, unsigned int priority), | 196 | TP_PROTO(struct kvm_vcpu *vcpu, unsigned int priority), |
156 | TP_ARGS(vcpu, priority), | 197 | TP_ARGS(vcpu, priority), |
@@ -167,8 +208,10 @@ TRACE_EVENT(kvm_booke_queue_irqprio, | |||
167 | __entry->pending = vcpu->arch.pending_exceptions; | 208 | __entry->pending = vcpu->arch.pending_exceptions; |
168 | ), | 209 | ), |
169 | 210 | ||
170 | TP_printk("vcpu=%x prio=%x pending=%lx", | 211 | TP_printk("vcpu=%x prio=%s pending=%lx", |
171 | __entry->cpu_nr, __entry->priority, __entry->pending) | 212 | __entry->cpu_nr, |
213 | __print_symbolic(__entry->priority, kvm_trace_symbol_irqprio), | ||
214 | __entry->pending) | ||
172 | ); | 215 | ); |
173 | 216 | ||
174 | #endif | 217 | #endif |
diff --git a/arch/powerpc/kvm/trace_hv.h b/arch/powerpc/kvm/trace_hv.h new file mode 100644 index 000000000000..33d9daff5783 --- /dev/null +++ b/arch/powerpc/kvm/trace_hv.h | |||
@@ -0,0 +1,477 @@ | |||
1 | #if !defined(_TRACE_KVM_HV_H) || defined(TRACE_HEADER_MULTI_READ) | ||
2 | #define _TRACE_KVM_HV_H | ||
3 | |||
4 | #include <linux/tracepoint.h> | ||
5 | #include "trace_book3s.h" | ||
6 | #include <asm/hvcall.h> | ||
7 | #include <asm/kvm_asm.h> | ||
8 | |||
9 | #undef TRACE_SYSTEM | ||
10 | #define TRACE_SYSTEM kvm_hv | ||
11 | #define TRACE_INCLUDE_PATH . | ||
12 | #define TRACE_INCLUDE_FILE trace_hv | ||
13 | |||
14 | #define kvm_trace_symbol_hcall \ | ||
15 | {H_REMOVE, "H_REMOVE"}, \ | ||
16 | {H_ENTER, "H_ENTER"}, \ | ||
17 | {H_READ, "H_READ"}, \ | ||
18 | {H_CLEAR_MOD, "H_CLEAR_MOD"}, \ | ||
19 | {H_CLEAR_REF, "H_CLEAR_REF"}, \ | ||
20 | {H_PROTECT, "H_PROTECT"}, \ | ||
21 | {H_GET_TCE, "H_GET_TCE"}, \ | ||
22 | {H_PUT_TCE, "H_PUT_TCE"}, \ | ||
23 | {H_SET_SPRG0, "H_SET_SPRG0"}, \ | ||
24 | {H_SET_DABR, "H_SET_DABR"}, \ | ||
25 | {H_PAGE_INIT, "H_PAGE_INIT"}, \ | ||
26 | {H_SET_ASR, "H_SET_ASR"}, \ | ||
27 | {H_ASR_ON, "H_ASR_ON"}, \ | ||
28 | {H_ASR_OFF, "H_ASR_OFF"}, \ | ||
29 | {H_LOGICAL_CI_LOAD, "H_LOGICAL_CI_LOAD"}, \ | ||
30 | {H_LOGICAL_CI_STORE, "H_LOGICAL_CI_STORE"}, \ | ||
31 | {H_LOGICAL_CACHE_LOAD, "H_LOGICAL_CACHE_LOAD"}, \ | ||
32 | {H_LOGICAL_CACHE_STORE, "H_LOGICAL_CACHE_STORE"}, \ | ||
33 | {H_LOGICAL_ICBI, "H_LOGICAL_ICBI"}, \ | ||
34 | {H_LOGICAL_DCBF, "H_LOGICAL_DCBF"}, \ | ||
35 | {H_GET_TERM_CHAR, "H_GET_TERM_CHAR"}, \ | ||
36 | {H_PUT_TERM_CHAR, "H_PUT_TERM_CHAR"}, \ | ||
37 | {H_REAL_TO_LOGICAL, "H_REAL_TO_LOGICAL"}, \ | ||
38 | {H_HYPERVISOR_DATA, "H_HYPERVISOR_DATA"}, \ | ||
39 | {H_EOI, "H_EOI"}, \ | ||
40 | {H_CPPR, "H_CPPR"}, \ | ||
41 | {H_IPI, "H_IPI"}, \ | ||
42 | {H_IPOLL, "H_IPOLL"}, \ | ||
43 | {H_XIRR, "H_XIRR"}, \ | ||
44 | {H_PERFMON, "H_PERFMON"}, \ | ||
45 | {H_MIGRATE_DMA, "H_MIGRATE_DMA"}, \ | ||
46 | {H_REGISTER_VPA, "H_REGISTER_VPA"}, \ | ||
47 | {H_CEDE, "H_CEDE"}, \ | ||
48 | {H_CONFER, "H_CONFER"}, \ | ||
49 | {H_PROD, "H_PROD"}, \ | ||
50 | {H_GET_PPP, "H_GET_PPP"}, \ | ||
51 | {H_SET_PPP, "H_SET_PPP"}, \ | ||
52 | {H_PURR, "H_PURR"}, \ | ||
53 | {H_PIC, "H_PIC"}, \ | ||
54 | {H_REG_CRQ, "H_REG_CRQ"}, \ | ||
55 | {H_FREE_CRQ, "H_FREE_CRQ"}, \ | ||
56 | {H_VIO_SIGNAL, "H_VIO_SIGNAL"}, \ | ||
57 | {H_SEND_CRQ, "H_SEND_CRQ"}, \ | ||
58 | {H_COPY_RDMA, "H_COPY_RDMA"}, \ | ||
59 | {H_REGISTER_LOGICAL_LAN, "H_REGISTER_LOGICAL_LAN"}, \ | ||
60 | {H_FREE_LOGICAL_LAN, "H_FREE_LOGICAL_LAN"}, \ | ||
61 | {H_ADD_LOGICAL_LAN_BUFFER, "H_ADD_LOGICAL_LAN_BUFFER"}, \ | ||
62 | {H_SEND_LOGICAL_LAN, "H_SEND_LOGICAL_LAN"}, \ | ||
63 | {H_BULK_REMOVE, "H_BULK_REMOVE"}, \ | ||
64 | {H_MULTICAST_CTRL, "H_MULTICAST_CTRL"}, \ | ||
65 | {H_SET_XDABR, "H_SET_XDABR"}, \ | ||
66 | {H_STUFF_TCE, "H_STUFF_TCE"}, \ | ||
67 | {H_PUT_TCE_INDIRECT, "H_PUT_TCE_INDIRECT"}, \ | ||
68 | {H_CHANGE_LOGICAL_LAN_MAC, "H_CHANGE_LOGICAL_LAN_MAC"}, \ | ||
69 | {H_VTERM_PARTNER_INFO, "H_VTERM_PARTNER_INFO"}, \ | ||
70 | {H_REGISTER_VTERM, "H_REGISTER_VTERM"}, \ | ||
71 | {H_FREE_VTERM, "H_FREE_VTERM"}, \ | ||
72 | {H_RESET_EVENTS, "H_RESET_EVENTS"}, \ | ||
73 | {H_ALLOC_RESOURCE, "H_ALLOC_RESOURCE"}, \ | ||
74 | {H_FREE_RESOURCE, "H_FREE_RESOURCE"}, \ | ||
75 | {H_MODIFY_QP, "H_MODIFY_QP"}, \ | ||
76 | {H_QUERY_QP, "H_QUERY_QP"}, \ | ||
77 | {H_REREGISTER_PMR, "H_REREGISTER_PMR"}, \ | ||
78 | {H_REGISTER_SMR, "H_REGISTER_SMR"}, \ | ||
79 | {H_QUERY_MR, "H_QUERY_MR"}, \ | ||
80 | {H_QUERY_MW, "H_QUERY_MW"}, \ | ||
81 | {H_QUERY_HCA, "H_QUERY_HCA"}, \ | ||
82 | {H_QUERY_PORT, "H_QUERY_PORT"}, \ | ||
83 | {H_MODIFY_PORT, "H_MODIFY_PORT"}, \ | ||
84 | {H_DEFINE_AQP1, "H_DEFINE_AQP1"}, \ | ||
85 | {H_GET_TRACE_BUFFER, "H_GET_TRACE_BUFFER"}, \ | ||
86 | {H_DEFINE_AQP0, "H_DEFINE_AQP0"}, \ | ||
87 | {H_RESIZE_MR, "H_RESIZE_MR"}, \ | ||
88 | {H_ATTACH_MCQP, "H_ATTACH_MCQP"}, \ | ||
89 | {H_DETACH_MCQP, "H_DETACH_MCQP"}, \ | ||
90 | {H_CREATE_RPT, "H_CREATE_RPT"}, \ | ||
91 | {H_REMOVE_RPT, "H_REMOVE_RPT"}, \ | ||
92 | {H_REGISTER_RPAGES, "H_REGISTER_RPAGES"}, \ | ||
93 | {H_DISABLE_AND_GETC, "H_DISABLE_AND_GETC"}, \ | ||
94 | {H_ERROR_DATA, "H_ERROR_DATA"}, \ | ||
95 | {H_GET_HCA_INFO, "H_GET_HCA_INFO"}, \ | ||
96 | {H_GET_PERF_COUNT, "H_GET_PERF_COUNT"}, \ | ||
97 | {H_MANAGE_TRACE, "H_MANAGE_TRACE"}, \ | ||
98 | {H_FREE_LOGICAL_LAN_BUFFER, "H_FREE_LOGICAL_LAN_BUFFER"}, \ | ||
99 | {H_QUERY_INT_STATE, "H_QUERY_INT_STATE"}, \ | ||
100 | {H_POLL_PENDING, "H_POLL_PENDING"}, \ | ||
101 | {H_ILLAN_ATTRIBUTES, "H_ILLAN_ATTRIBUTES"}, \ | ||
102 | {H_MODIFY_HEA_QP, "H_MODIFY_HEA_QP"}, \ | ||
103 | {H_QUERY_HEA_QP, "H_QUERY_HEA_QP"}, \ | ||
104 | {H_QUERY_HEA, "H_QUERY_HEA"}, \ | ||
105 | {H_QUERY_HEA_PORT, "H_QUERY_HEA_PORT"}, \ | ||
106 | {H_MODIFY_HEA_PORT, "H_MODIFY_HEA_PORT"}, \ | ||
107 | {H_REG_BCMC, "H_REG_BCMC"}, \ | ||
108 | {H_DEREG_BCMC, "H_DEREG_BCMC"}, \ | ||
109 | {H_REGISTER_HEA_RPAGES, "H_REGISTER_HEA_RPAGES"}, \ | ||
110 | {H_DISABLE_AND_GET_HEA, "H_DISABLE_AND_GET_HEA"}, \ | ||
111 | {H_GET_HEA_INFO, "H_GET_HEA_INFO"}, \ | ||
112 | {H_ALLOC_HEA_RESOURCE, "H_ALLOC_HEA_RESOURCE"}, \ | ||
113 | {H_ADD_CONN, "H_ADD_CONN"}, \ | ||
114 | {H_DEL_CONN, "H_DEL_CONN"}, \ | ||
115 | {H_JOIN, "H_JOIN"}, \ | ||
116 | {H_VASI_STATE, "H_VASI_STATE"}, \ | ||
117 | {H_ENABLE_CRQ, "H_ENABLE_CRQ"}, \ | ||
118 | {H_GET_EM_PARMS, "H_GET_EM_PARMS"}, \ | ||
119 | {H_SET_MPP, "H_SET_MPP"}, \ | ||
120 | {H_GET_MPP, "H_GET_MPP"}, \ | ||
121 | {H_HOME_NODE_ASSOCIATIVITY, "H_HOME_NODE_ASSOCIATIVITY"}, \ | ||
122 | {H_BEST_ENERGY, "H_BEST_ENERGY"}, \ | ||
123 | {H_XIRR_X, "H_XIRR_X"}, \ | ||
124 | {H_RANDOM, "H_RANDOM"}, \ | ||
125 | {H_COP, "H_COP"}, \ | ||
126 | {H_GET_MPP_X, "H_GET_MPP_X"}, \ | ||
127 | {H_SET_MODE, "H_SET_MODE"}, \ | ||
128 | {H_RTAS, "H_RTAS"} | ||
129 | |||
130 | #define kvm_trace_symbol_kvmret \ | ||
131 | {RESUME_GUEST, "RESUME_GUEST"}, \ | ||
132 | {RESUME_GUEST_NV, "RESUME_GUEST_NV"}, \ | ||
133 | {RESUME_HOST, "RESUME_HOST"}, \ | ||
134 | {RESUME_HOST_NV, "RESUME_HOST_NV"} | ||
135 | |||
136 | #define kvm_trace_symbol_hcall_rc \ | ||
137 | {H_SUCCESS, "H_SUCCESS"}, \ | ||
138 | {H_BUSY, "H_BUSY"}, \ | ||
139 | {H_CLOSED, "H_CLOSED"}, \ | ||
140 | {H_NOT_AVAILABLE, "H_NOT_AVAILABLE"}, \ | ||
141 | {H_CONSTRAINED, "H_CONSTRAINED"}, \ | ||
142 | {H_PARTIAL, "H_PARTIAL"}, \ | ||
143 | {H_IN_PROGRESS, "H_IN_PROGRESS"}, \ | ||
144 | {H_PAGE_REGISTERED, "H_PAGE_REGISTERED"}, \ | ||
145 | {H_PARTIAL_STORE, "H_PARTIAL_STORE"}, \ | ||
146 | {H_PENDING, "H_PENDING"}, \ | ||
147 | {H_CONTINUE, "H_CONTINUE"}, \ | ||
148 | {H_LONG_BUSY_START_RANGE, "H_LONG_BUSY_START_RANGE"}, \ | ||
149 | {H_LONG_BUSY_ORDER_1_MSEC, "H_LONG_BUSY_ORDER_1_MSEC"}, \ | ||
150 | {H_LONG_BUSY_ORDER_10_MSEC, "H_LONG_BUSY_ORDER_10_MSEC"}, \ | ||
151 | {H_LONG_BUSY_ORDER_100_MSEC, "H_LONG_BUSY_ORDER_100_MSEC"}, \ | ||
152 | {H_LONG_BUSY_ORDER_1_SEC, "H_LONG_BUSY_ORDER_1_SEC"}, \ | ||
153 | {H_LONG_BUSY_ORDER_10_SEC, "H_LONG_BUSY_ORDER_10_SEC"}, \ | ||
154 | {H_LONG_BUSY_ORDER_100_SEC, "H_LONG_BUSY_ORDER_100_SEC"}, \ | ||
155 | {H_LONG_BUSY_END_RANGE, "H_LONG_BUSY_END_RANGE"}, \ | ||
156 | {H_TOO_HARD, "H_TOO_HARD"}, \ | ||
157 | {H_HARDWARE, "H_HARDWARE"}, \ | ||
158 | {H_FUNCTION, "H_FUNCTION"}, \ | ||
159 | {H_PRIVILEGE, "H_PRIVILEGE"}, \ | ||
160 | {H_PARAMETER, "H_PARAMETER"}, \ | ||
161 | {H_BAD_MODE, "H_BAD_MODE"}, \ | ||
162 | {H_PTEG_FULL, "H_PTEG_FULL"}, \ | ||
163 | {H_NOT_FOUND, "H_NOT_FOUND"}, \ | ||
164 | {H_RESERVED_DABR, "H_RESERVED_DABR"}, \ | ||
165 | {H_NO_MEM, "H_NO_MEM"}, \ | ||
166 | {H_AUTHORITY, "H_AUTHORITY"}, \ | ||
167 | {H_PERMISSION, "H_PERMISSION"}, \ | ||
168 | {H_DROPPED, "H_DROPPED"}, \ | ||
169 | {H_SOURCE_PARM, "H_SOURCE_PARM"}, \ | ||
170 | {H_DEST_PARM, "H_DEST_PARM"}, \ | ||
171 | {H_REMOTE_PARM, "H_REMOTE_PARM"}, \ | ||
172 | {H_RESOURCE, "H_RESOURCE"}, \ | ||
173 | {H_ADAPTER_PARM, "H_ADAPTER_PARM"}, \ | ||
174 | {H_RH_PARM, "H_RH_PARM"}, \ | ||
175 | {H_RCQ_PARM, "H_RCQ_PARM"}, \ | ||
176 | {H_SCQ_PARM, "H_SCQ_PARM"}, \ | ||
177 | {H_EQ_PARM, "H_EQ_PARM"}, \ | ||
178 | {H_RT_PARM, "H_RT_PARM"}, \ | ||
179 | {H_ST_PARM, "H_ST_PARM"}, \ | ||
180 | {H_SIGT_PARM, "H_SIGT_PARM"}, \ | ||
181 | {H_TOKEN_PARM, "H_TOKEN_PARM"}, \ | ||
182 | {H_MLENGTH_PARM, "H_MLENGTH_PARM"}, \ | ||
183 | {H_MEM_PARM, "H_MEM_PARM"}, \ | ||
184 | {H_MEM_ACCESS_PARM, "H_MEM_ACCESS_PARM"}, \ | ||
185 | {H_ATTR_PARM, "H_ATTR_PARM"}, \ | ||
186 | {H_PORT_PARM, "H_PORT_PARM"}, \ | ||
187 | {H_MCG_PARM, "H_MCG_PARM"}, \ | ||
188 | {H_VL_PARM, "H_VL_PARM"}, \ | ||
189 | {H_TSIZE_PARM, "H_TSIZE_PARM"}, \ | ||
190 | {H_TRACE_PARM, "H_TRACE_PARM"}, \ | ||
191 | {H_MASK_PARM, "H_MASK_PARM"}, \ | ||
192 | {H_MCG_FULL, "H_MCG_FULL"}, \ | ||
193 | {H_ALIAS_EXIST, "H_ALIAS_EXIST"}, \ | ||
194 | {H_P_COUNTER, "H_P_COUNTER"}, \ | ||
195 | {H_TABLE_FULL, "H_TABLE_FULL"}, \ | ||
196 | {H_ALT_TABLE, "H_ALT_TABLE"}, \ | ||
197 | {H_MR_CONDITION, "H_MR_CONDITION"}, \ | ||
198 | {H_NOT_ENOUGH_RESOURCES, "H_NOT_ENOUGH_RESOURCES"}, \ | ||
199 | {H_R_STATE, "H_R_STATE"}, \ | ||
200 | {H_RESCINDED, "H_RESCINDED"}, \ | ||
201 | {H_P2, "H_P2"}, \ | ||
202 | {H_P3, "H_P3"}, \ | ||
203 | {H_P4, "H_P4"}, \ | ||
204 | {H_P5, "H_P5"}, \ | ||
205 | {H_P6, "H_P6"}, \ | ||
206 | {H_P7, "H_P7"}, \ | ||
207 | {H_P8, "H_P8"}, \ | ||
208 | {H_P9, "H_P9"}, \ | ||
209 | {H_TOO_BIG, "H_TOO_BIG"}, \ | ||
210 | {H_OVERLAP, "H_OVERLAP"}, \ | ||
211 | {H_INTERRUPT, "H_INTERRUPT"}, \ | ||
212 | {H_BAD_DATA, "H_BAD_DATA"}, \ | ||
213 | {H_NOT_ACTIVE, "H_NOT_ACTIVE"}, \ | ||
214 | {H_SG_LIST, "H_SG_LIST"}, \ | ||
215 | {H_OP_MODE, "H_OP_MODE"}, \ | ||
216 | {H_COP_HW, "H_COP_HW"}, \ | ||
217 | {H_UNSUPPORTED_FLAG_START, "H_UNSUPPORTED_FLAG_START"}, \ | ||
218 | {H_UNSUPPORTED_FLAG_END, "H_UNSUPPORTED_FLAG_END"}, \ | ||
219 | {H_MULTI_THREADS_ACTIVE, "H_MULTI_THREADS_ACTIVE"}, \ | ||
220 | {H_OUTSTANDING_COP_OPS, "H_OUTSTANDING_COP_OPS"} | ||
221 | |||
222 | TRACE_EVENT(kvm_guest_enter, | ||
223 | TP_PROTO(struct kvm_vcpu *vcpu), | ||
224 | TP_ARGS(vcpu), | ||
225 | |||
226 | TP_STRUCT__entry( | ||
227 | __field(int, vcpu_id) | ||
228 | __field(unsigned long, pc) | ||
229 | __field(unsigned long, pending_exceptions) | ||
230 | __field(u8, ceded) | ||
231 | ), | ||
232 | |||
233 | TP_fast_assign( | ||
234 | __entry->vcpu_id = vcpu->vcpu_id; | ||
235 | __entry->pc = kvmppc_get_pc(vcpu); | ||
236 | __entry->ceded = vcpu->arch.ceded; | ||
237 | __entry->pending_exceptions = vcpu->arch.pending_exceptions; | ||
238 | ), | ||
239 | |||
240 | TP_printk("VCPU %d: pc=0x%lx pexcp=0x%lx ceded=%d", | ||
241 | __entry->vcpu_id, | ||
242 | __entry->pc, | ||
243 | __entry->pending_exceptions, __entry->ceded) | ||
244 | ); | ||
245 | |||
246 | TRACE_EVENT(kvm_guest_exit, | ||
247 | TP_PROTO(struct kvm_vcpu *vcpu), | ||
248 | TP_ARGS(vcpu), | ||
249 | |||
250 | TP_STRUCT__entry( | ||
251 | __field(int, vcpu_id) | ||
252 | __field(int, trap) | ||
253 | __field(unsigned long, pc) | ||
254 | __field(unsigned long, msr) | ||
255 | __field(u8, ceded) | ||
256 | ), | ||
257 | |||
258 | TP_fast_assign( | ||
259 | __entry->vcpu_id = vcpu->vcpu_id; | ||
260 | __entry->trap = vcpu->arch.trap; | ||
261 | __entry->ceded = vcpu->arch.ceded; | ||
262 | __entry->pc = kvmppc_get_pc(vcpu); | ||
263 | __entry->msr = vcpu->arch.shregs.msr; | ||
264 | ), | ||
265 | |||
266 | TP_printk("VCPU %d: trap=%s pc=0x%lx msr=0x%lx, ceded=%d", | ||
267 | __entry->vcpu_id, | ||
268 | __print_symbolic(__entry->trap, kvm_trace_symbol_exit), | ||
269 | __entry->pc, __entry->msr, __entry->ceded | ||
270 | ) | ||
271 | ); | ||
272 | |||
273 | TRACE_EVENT(kvm_page_fault_enter, | ||
274 | TP_PROTO(struct kvm_vcpu *vcpu, unsigned long *hptep, | ||
275 | struct kvm_memory_slot *memslot, unsigned long ea, | ||
276 | unsigned long dsisr), | ||
277 | |||
278 | TP_ARGS(vcpu, hptep, memslot, ea, dsisr), | ||
279 | |||
280 | TP_STRUCT__entry( | ||
281 | __field(int, vcpu_id) | ||
282 | __field(unsigned long, hpte_v) | ||
283 | __field(unsigned long, hpte_r) | ||
284 | __field(unsigned long, gpte_r) | ||
285 | __field(unsigned long, ea) | ||
286 | __field(u64, base_gfn) | ||
287 | __field(u32, slot_flags) | ||
288 | __field(u32, dsisr) | ||
289 | ), | ||
290 | |||
291 | TP_fast_assign( | ||
292 | __entry->vcpu_id = vcpu->vcpu_id; | ||
293 | __entry->hpte_v = hptep[0]; | ||
294 | __entry->hpte_r = hptep[1]; | ||
295 | __entry->gpte_r = hptep[2]; | ||
296 | __entry->ea = ea; | ||
297 | __entry->dsisr = dsisr; | ||
298 | __entry->base_gfn = memslot ? memslot->base_gfn : -1UL; | ||
299 | __entry->slot_flags = memslot ? memslot->flags : 0; | ||
300 | ), | ||
301 | |||
302 | TP_printk("VCPU %d: hpte=0x%lx:0x%lx guest=0x%lx ea=0x%lx,%x slot=0x%llx,0x%x", | ||
303 | __entry->vcpu_id, | ||
304 | __entry->hpte_v, __entry->hpte_r, __entry->gpte_r, | ||
305 | __entry->ea, __entry->dsisr, | ||
306 | __entry->base_gfn, __entry->slot_flags) | ||
307 | ); | ||
308 | |||
309 | TRACE_EVENT(kvm_page_fault_exit, | ||
310 | TP_PROTO(struct kvm_vcpu *vcpu, unsigned long *hptep, long ret), | ||
311 | |||
312 | TP_ARGS(vcpu, hptep, ret), | ||
313 | |||
314 | TP_STRUCT__entry( | ||
315 | __field(int, vcpu_id) | ||
316 | __field(unsigned long, hpte_v) | ||
317 | __field(unsigned long, hpte_r) | ||
318 | __field(long, ret) | ||
319 | ), | ||
320 | |||
321 | TP_fast_assign( | ||
322 | __entry->vcpu_id = vcpu->vcpu_id; | ||
323 | __entry->hpte_v = hptep[0]; | ||
324 | __entry->hpte_r = hptep[1]; | ||
325 | __entry->ret = ret; | ||
326 | ), | ||
327 | |||
328 | TP_printk("VCPU %d: hpte=0x%lx:0x%lx ret=0x%lx", | ||
329 | __entry->vcpu_id, | ||
330 | __entry->hpte_v, __entry->hpte_r, __entry->ret) | ||
331 | ); | ||
332 | |||
333 | TRACE_EVENT(kvm_hcall_enter, | ||
334 | TP_PROTO(struct kvm_vcpu *vcpu), | ||
335 | |||
336 | TP_ARGS(vcpu), | ||
337 | |||
338 | TP_STRUCT__entry( | ||
339 | __field(int, vcpu_id) | ||
340 | __field(unsigned long, req) | ||
341 | __field(unsigned long, gpr4) | ||
342 | __field(unsigned long, gpr5) | ||
343 | __field(unsigned long, gpr6) | ||
344 | __field(unsigned long, gpr7) | ||
345 | ), | ||
346 | |||
347 | TP_fast_assign( | ||
348 | __entry->vcpu_id = vcpu->vcpu_id; | ||
349 | __entry->req = kvmppc_get_gpr(vcpu, 3); | ||
350 | __entry->gpr4 = kvmppc_get_gpr(vcpu, 4); | ||
351 | __entry->gpr5 = kvmppc_get_gpr(vcpu, 5); | ||
352 | __entry->gpr6 = kvmppc_get_gpr(vcpu, 6); | ||
353 | __entry->gpr7 = kvmppc_get_gpr(vcpu, 7); | ||
354 | ), | ||
355 | |||
356 | TP_printk("VCPU %d: hcall=%s GPR4-7=0x%lx,0x%lx,0x%lx,0x%lx", | ||
357 | __entry->vcpu_id, | ||
358 | __print_symbolic(__entry->req, kvm_trace_symbol_hcall), | ||
359 | __entry->gpr4, __entry->gpr5, __entry->gpr6, __entry->gpr7) | ||
360 | ); | ||
361 | |||
362 | TRACE_EVENT(kvm_hcall_exit, | ||
363 | TP_PROTO(struct kvm_vcpu *vcpu, int ret), | ||
364 | |||
365 | TP_ARGS(vcpu, ret), | ||
366 | |||
367 | TP_STRUCT__entry( | ||
368 | __field(int, vcpu_id) | ||
369 | __field(unsigned long, ret) | ||
370 | __field(unsigned long, hcall_rc) | ||
371 | ), | ||
372 | |||
373 | TP_fast_assign( | ||
374 | __entry->vcpu_id = vcpu->vcpu_id; | ||
375 | __entry->ret = ret; | ||
376 | __entry->hcall_rc = kvmppc_get_gpr(vcpu, 3); | ||
377 | ), | ||
378 | |||
379 | TP_printk("VCPU %d: ret=%s hcall_rc=%s", | ||
380 | __entry->vcpu_id, | ||
381 | __print_symbolic(__entry->ret, kvm_trace_symbol_kvmret), | ||
382 | __print_symbolic(__entry->ret & RESUME_FLAG_HOST ? | ||
383 | H_TOO_HARD : __entry->hcall_rc, | ||
384 | kvm_trace_symbol_hcall_rc)) | ||
385 | ); | ||
386 | |||
387 | TRACE_EVENT(kvmppc_run_core, | ||
388 | TP_PROTO(struct kvmppc_vcore *vc, int where), | ||
389 | |||
390 | TP_ARGS(vc, where), | ||
391 | |||
392 | TP_STRUCT__entry( | ||
393 | __field(int, n_runnable) | ||
394 | __field(int, runner_vcpu) | ||
395 | __field(int, where) | ||
396 | __field(pid_t, tgid) | ||
397 | ), | ||
398 | |||
399 | TP_fast_assign( | ||
400 | __entry->runner_vcpu = vc->runner->vcpu_id; | ||
401 | __entry->n_runnable = vc->n_runnable; | ||
402 | __entry->where = where; | ||
403 | __entry->tgid = current->tgid; | ||
404 | ), | ||
405 | |||
406 | TP_printk("%s runner_vcpu==%d runnable=%d tgid=%d", | ||
407 | __entry->where ? "Exit" : "Enter", | ||
408 | __entry->runner_vcpu, __entry->n_runnable, __entry->tgid) | ||
409 | ); | ||
410 | |||
411 | TRACE_EVENT(kvmppc_vcore_blocked, | ||
412 | TP_PROTO(struct kvmppc_vcore *vc, int where), | ||
413 | |||
414 | TP_ARGS(vc, where), | ||
415 | |||
416 | TP_STRUCT__entry( | ||
417 | __field(int, n_runnable) | ||
418 | __field(int, runner_vcpu) | ||
419 | __field(int, where) | ||
420 | __field(pid_t, tgid) | ||
421 | ), | ||
422 | |||
423 | TP_fast_assign( | ||
424 | __entry->runner_vcpu = vc->runner->vcpu_id; | ||
425 | __entry->n_runnable = vc->n_runnable; | ||
426 | __entry->where = where; | ||
427 | __entry->tgid = current->tgid; | ||
428 | ), | ||
429 | |||
430 | TP_printk("%s runner_vcpu=%d runnable=%d tgid=%d", | ||
431 | __entry->where ? "Exit" : "Enter", | ||
432 | __entry->runner_vcpu, __entry->n_runnable, __entry->tgid) | ||
433 | ); | ||
434 | |||
435 | TRACE_EVENT(kvmppc_run_vcpu_enter, | ||
436 | TP_PROTO(struct kvm_vcpu *vcpu), | ||
437 | |||
438 | TP_ARGS(vcpu), | ||
439 | |||
440 | TP_STRUCT__entry( | ||
441 | __field(int, vcpu_id) | ||
442 | __field(pid_t, tgid) | ||
443 | ), | ||
444 | |||
445 | TP_fast_assign( | ||
446 | __entry->vcpu_id = vcpu->vcpu_id; | ||
447 | __entry->tgid = current->tgid; | ||
448 | ), | ||
449 | |||
450 | TP_printk("VCPU %d: tgid=%d", __entry->vcpu_id, __entry->tgid) | ||
451 | ); | ||
452 | |||
453 | TRACE_EVENT(kvmppc_run_vcpu_exit, | ||
454 | TP_PROTO(struct kvm_vcpu *vcpu, struct kvm_run *run), | ||
455 | |||
456 | TP_ARGS(vcpu, run), | ||
457 | |||
458 | TP_STRUCT__entry( | ||
459 | __field(int, vcpu_id) | ||
460 | __field(int, exit) | ||
461 | __field(int, ret) | ||
462 | ), | ||
463 | |||
464 | TP_fast_assign( | ||
465 | __entry->vcpu_id = vcpu->vcpu_id; | ||
466 | __entry->exit = run->exit_reason; | ||
467 | __entry->ret = vcpu->arch.ret; | ||
468 | ), | ||
469 | |||
470 | TP_printk("VCPU %d: exit=%d, ret=%d", | ||
471 | __entry->vcpu_id, __entry->exit, __entry->ret) | ||
472 | ); | ||
473 | |||
474 | #endif /* _TRACE_KVM_HV_H */ | ||
475 | |||
476 | /* This part must be outside protection */ | ||
477 | #include <trace/define_trace.h> | ||
diff --git a/arch/powerpc/kvm/trace_pr.h b/arch/powerpc/kvm/trace_pr.h index e1357cd8dc1f..810507cb688a 100644 --- a/arch/powerpc/kvm/trace_pr.h +++ b/arch/powerpc/kvm/trace_pr.h | |||
@@ -3,36 +3,13 @@ | |||
3 | #define _TRACE_KVM_PR_H | 3 | #define _TRACE_KVM_PR_H |
4 | 4 | ||
5 | #include <linux/tracepoint.h> | 5 | #include <linux/tracepoint.h> |
6 | #include "trace_book3s.h" | ||
6 | 7 | ||
7 | #undef TRACE_SYSTEM | 8 | #undef TRACE_SYSTEM |
8 | #define TRACE_SYSTEM kvm_pr | 9 | #define TRACE_SYSTEM kvm_pr |
9 | #define TRACE_INCLUDE_PATH . | 10 | #define TRACE_INCLUDE_PATH . |
10 | #define TRACE_INCLUDE_FILE trace_pr | 11 | #define TRACE_INCLUDE_FILE trace_pr |
11 | 12 | ||
12 | #define kvm_trace_symbol_exit \ | ||
13 | {0x100, "SYSTEM_RESET"}, \ | ||
14 | {0x200, "MACHINE_CHECK"}, \ | ||
15 | {0x300, "DATA_STORAGE"}, \ | ||
16 | {0x380, "DATA_SEGMENT"}, \ | ||
17 | {0x400, "INST_STORAGE"}, \ | ||
18 | {0x480, "INST_SEGMENT"}, \ | ||
19 | {0x500, "EXTERNAL"}, \ | ||
20 | {0x501, "EXTERNAL_LEVEL"}, \ | ||
21 | {0x502, "EXTERNAL_HV"}, \ | ||
22 | {0x600, "ALIGNMENT"}, \ | ||
23 | {0x700, "PROGRAM"}, \ | ||
24 | {0x800, "FP_UNAVAIL"}, \ | ||
25 | {0x900, "DECREMENTER"}, \ | ||
26 | {0x980, "HV_DECREMENTER"}, \ | ||
27 | {0xc00, "SYSCALL"}, \ | ||
28 | {0xd00, "TRACE"}, \ | ||
29 | {0xe00, "H_DATA_STORAGE"}, \ | ||
30 | {0xe20, "H_INST_STORAGE"}, \ | ||
31 | {0xe40, "H_EMUL_ASSIST"}, \ | ||
32 | {0xf00, "PERFMON"}, \ | ||
33 | {0xf20, "ALTIVEC"}, \ | ||
34 | {0xf40, "VSX"} | ||
35 | |||
36 | TRACE_EVENT(kvm_book3s_reenter, | 13 | TRACE_EVENT(kvm_book3s_reenter, |
37 | TP_PROTO(int r, struct kvm_vcpu *vcpu), | 14 | TP_PROTO(int r, struct kvm_vcpu *vcpu), |
38 | TP_ARGS(r, vcpu), | 15 | TP_ARGS(r, vcpu), |
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index 2175f911a73a..9cba74d5d853 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h | |||
@@ -123,7 +123,7 @@ struct kvm_s390_sie_block { | |||
123 | #define ICPT_PARTEXEC 0x38 | 123 | #define ICPT_PARTEXEC 0x38 |
124 | #define ICPT_IOINST 0x40 | 124 | #define ICPT_IOINST 0x40 |
125 | __u8 icptcode; /* 0x0050 */ | 125 | __u8 icptcode; /* 0x0050 */ |
126 | __u8 reserved51; /* 0x0051 */ | 126 | __u8 icptstatus; /* 0x0051 */ |
127 | __u16 ihcpu; /* 0x0052 */ | 127 | __u16 ihcpu; /* 0x0052 */ |
128 | __u8 reserved54[2]; /* 0x0054 */ | 128 | __u8 reserved54[2]; /* 0x0054 */ |
129 | __u16 ipa; /* 0x0056 */ | 129 | __u16 ipa; /* 0x0056 */ |
@@ -226,10 +226,17 @@ struct kvm_vcpu_stat { | |||
226 | u32 instruction_sigp_sense_running; | 226 | u32 instruction_sigp_sense_running; |
227 | u32 instruction_sigp_external_call; | 227 | u32 instruction_sigp_external_call; |
228 | u32 instruction_sigp_emergency; | 228 | u32 instruction_sigp_emergency; |
229 | u32 instruction_sigp_cond_emergency; | ||
230 | u32 instruction_sigp_start; | ||
229 | u32 instruction_sigp_stop; | 231 | u32 instruction_sigp_stop; |
232 | u32 instruction_sigp_stop_store_status; | ||
233 | u32 instruction_sigp_store_status; | ||
230 | u32 instruction_sigp_arch; | 234 | u32 instruction_sigp_arch; |
231 | u32 instruction_sigp_prefix; | 235 | u32 instruction_sigp_prefix; |
232 | u32 instruction_sigp_restart; | 236 | u32 instruction_sigp_restart; |
237 | u32 instruction_sigp_init_cpu_reset; | ||
238 | u32 instruction_sigp_cpu_reset; | ||
239 | u32 instruction_sigp_unknown; | ||
233 | u32 diagnose_10; | 240 | u32 diagnose_10; |
234 | u32 diagnose_44; | 241 | u32 diagnose_44; |
235 | u32 diagnose_9c; | 242 | u32 diagnose_9c; |
@@ -288,6 +295,79 @@ struct kvm_vcpu_stat { | |||
288 | #define PGM_PER 0x80 | 295 | #define PGM_PER 0x80 |
289 | #define PGM_CRYPTO_OPERATION 0x119 | 296 | #define PGM_CRYPTO_OPERATION 0x119 |
290 | 297 | ||
298 | /* irq types in order of priority */ | ||
299 | enum irq_types { | ||
300 | IRQ_PEND_MCHK_EX = 0, | ||
301 | IRQ_PEND_SVC, | ||
302 | IRQ_PEND_PROG, | ||
303 | IRQ_PEND_MCHK_REP, | ||
304 | IRQ_PEND_EXT_IRQ_KEY, | ||
305 | IRQ_PEND_EXT_MALFUNC, | ||
306 | IRQ_PEND_EXT_EMERGENCY, | ||
307 | IRQ_PEND_EXT_EXTERNAL, | ||
308 | IRQ_PEND_EXT_CLOCK_COMP, | ||
309 | IRQ_PEND_EXT_CPU_TIMER, | ||
310 | IRQ_PEND_EXT_TIMING, | ||
311 | IRQ_PEND_EXT_SERVICE, | ||
312 | IRQ_PEND_EXT_HOST, | ||
313 | IRQ_PEND_PFAULT_INIT, | ||
314 | IRQ_PEND_PFAULT_DONE, | ||
315 | IRQ_PEND_VIRTIO, | ||
316 | IRQ_PEND_IO_ISC_0, | ||
317 | IRQ_PEND_IO_ISC_1, | ||
318 | IRQ_PEND_IO_ISC_2, | ||
319 | IRQ_PEND_IO_ISC_3, | ||
320 | IRQ_PEND_IO_ISC_4, | ||
321 | IRQ_PEND_IO_ISC_5, | ||
322 | IRQ_PEND_IO_ISC_6, | ||
323 | IRQ_PEND_IO_ISC_7, | ||
324 | IRQ_PEND_SIGP_STOP, | ||
325 | IRQ_PEND_RESTART, | ||
326 | IRQ_PEND_SET_PREFIX, | ||
327 | IRQ_PEND_COUNT | ||
328 | }; | ||
329 | |||
330 | /* | ||
331 | * Repressible (non-floating) machine check interrupts | ||
332 | * subclass bits in MCIC | ||
333 | */ | ||
334 | #define MCHK_EXTD_BIT 58 | ||
335 | #define MCHK_DEGR_BIT 56 | ||
336 | #define MCHK_WARN_BIT 55 | ||
337 | #define MCHK_REP_MASK ((1UL << MCHK_DEGR_BIT) | \ | ||
338 | (1UL << MCHK_EXTD_BIT) | \ | ||
339 | (1UL << MCHK_WARN_BIT)) | ||
340 | |||
341 | /* Exigent machine check interrupts subclass bits in MCIC */ | ||
342 | #define MCHK_SD_BIT 63 | ||
343 | #define MCHK_PD_BIT 62 | ||
344 | #define MCHK_EX_MASK ((1UL << MCHK_SD_BIT) | (1UL << MCHK_PD_BIT)) | ||
345 | |||
346 | #define IRQ_PEND_EXT_MASK ((1UL << IRQ_PEND_EXT_IRQ_KEY) | \ | ||
347 | (1UL << IRQ_PEND_EXT_CLOCK_COMP) | \ | ||
348 | (1UL << IRQ_PEND_EXT_CPU_TIMER) | \ | ||
349 | (1UL << IRQ_PEND_EXT_MALFUNC) | \ | ||
350 | (1UL << IRQ_PEND_EXT_EMERGENCY) | \ | ||
351 | (1UL << IRQ_PEND_EXT_EXTERNAL) | \ | ||
352 | (1UL << IRQ_PEND_EXT_TIMING) | \ | ||
353 | (1UL << IRQ_PEND_EXT_HOST) | \ | ||
354 | (1UL << IRQ_PEND_EXT_SERVICE) | \ | ||
355 | (1UL << IRQ_PEND_VIRTIO) | \ | ||
356 | (1UL << IRQ_PEND_PFAULT_INIT) | \ | ||
357 | (1UL << IRQ_PEND_PFAULT_DONE)) | ||
358 | |||
359 | #define IRQ_PEND_IO_MASK ((1UL << IRQ_PEND_IO_ISC_0) | \ | ||
360 | (1UL << IRQ_PEND_IO_ISC_1) | \ | ||
361 | (1UL << IRQ_PEND_IO_ISC_2) | \ | ||
362 | (1UL << IRQ_PEND_IO_ISC_3) | \ | ||
363 | (1UL << IRQ_PEND_IO_ISC_4) | \ | ||
364 | (1UL << IRQ_PEND_IO_ISC_5) | \ | ||
365 | (1UL << IRQ_PEND_IO_ISC_6) | \ | ||
366 | (1UL << IRQ_PEND_IO_ISC_7)) | ||
367 | |||
368 | #define IRQ_PEND_MCHK_MASK ((1UL << IRQ_PEND_MCHK_REP) | \ | ||
369 | (1UL << IRQ_PEND_MCHK_EX)) | ||
370 | |||
291 | struct kvm_s390_interrupt_info { | 371 | struct kvm_s390_interrupt_info { |
292 | struct list_head list; | 372 | struct list_head list; |
293 | u64 type; | 373 | u64 type; |
@@ -306,14 +386,25 @@ struct kvm_s390_interrupt_info { | |||
306 | #define ACTION_STORE_ON_STOP (1<<0) | 386 | #define ACTION_STORE_ON_STOP (1<<0) |
307 | #define ACTION_STOP_ON_STOP (1<<1) | 387 | #define ACTION_STOP_ON_STOP (1<<1) |
308 | 388 | ||
389 | struct kvm_s390_irq_payload { | ||
390 | struct kvm_s390_io_info io; | ||
391 | struct kvm_s390_ext_info ext; | ||
392 | struct kvm_s390_pgm_info pgm; | ||
393 | struct kvm_s390_emerg_info emerg; | ||
394 | struct kvm_s390_extcall_info extcall; | ||
395 | struct kvm_s390_prefix_info prefix; | ||
396 | struct kvm_s390_mchk_info mchk; | ||
397 | }; | ||
398 | |||
309 | struct kvm_s390_local_interrupt { | 399 | struct kvm_s390_local_interrupt { |
310 | spinlock_t lock; | 400 | spinlock_t lock; |
311 | struct list_head list; | ||
312 | atomic_t active; | ||
313 | struct kvm_s390_float_interrupt *float_int; | 401 | struct kvm_s390_float_interrupt *float_int; |
314 | wait_queue_head_t *wq; | 402 | wait_queue_head_t *wq; |
315 | atomic_t *cpuflags; | 403 | atomic_t *cpuflags; |
316 | unsigned int action_bits; | 404 | unsigned int action_bits; |
405 | DECLARE_BITMAP(sigp_emerg_pending, KVM_MAX_VCPUS); | ||
406 | struct kvm_s390_irq_payload irq; | ||
407 | unsigned long pending_irqs; | ||
317 | }; | 408 | }; |
318 | 409 | ||
319 | struct kvm_s390_float_interrupt { | 410 | struct kvm_s390_float_interrupt { |
@@ -434,6 +525,8 @@ struct kvm_arch{ | |||
434 | int user_cpu_state_ctrl; | 525 | int user_cpu_state_ctrl; |
435 | struct s390_io_adapter *adapters[MAX_S390_IO_ADAPTERS]; | 526 | struct s390_io_adapter *adapters[MAX_S390_IO_ADAPTERS]; |
436 | wait_queue_head_t ipte_wq; | 527 | wait_queue_head_t ipte_wq; |
528 | int ipte_lock_count; | ||
529 | struct mutex ipte_mutex; | ||
437 | spinlock_t start_stop_lock; | 530 | spinlock_t start_stop_lock; |
438 | struct kvm_s390_crypto crypto; | 531 | struct kvm_s390_crypto crypto; |
439 | }; | 532 | }; |
diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h index e510b9460efa..3009c2ba46d2 100644 --- a/arch/s390/include/asm/pgalloc.h +++ b/arch/s390/include/asm/pgalloc.h | |||
@@ -24,6 +24,7 @@ void page_table_free_rcu(struct mmu_gather *, unsigned long *, unsigned long); | |||
24 | 24 | ||
25 | int set_guest_storage_key(struct mm_struct *mm, unsigned long addr, | 25 | int set_guest_storage_key(struct mm_struct *mm, unsigned long addr, |
26 | unsigned long key, bool nq); | 26 | unsigned long key, bool nq); |
27 | unsigned long get_guest_storage_key(struct mm_struct *mm, unsigned long addr); | ||
27 | 28 | ||
28 | static inline void clear_table(unsigned long *s, unsigned long val, size_t n) | 29 | static inline void clear_table(unsigned long *s, unsigned long val, size_t n) |
29 | { | 30 | { |
diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h index 49576115dbb7..fad4ae23ece0 100644 --- a/arch/s390/include/asm/sigp.h +++ b/arch/s390/include/asm/sigp.h | |||
@@ -10,6 +10,7 @@ | |||
10 | #define SIGP_RESTART 6 | 10 | #define SIGP_RESTART 6 |
11 | #define SIGP_STOP_AND_STORE_STATUS 9 | 11 | #define SIGP_STOP_AND_STORE_STATUS 9 |
12 | #define SIGP_INITIAL_CPU_RESET 11 | 12 | #define SIGP_INITIAL_CPU_RESET 11 |
13 | #define SIGP_CPU_RESET 12 | ||
13 | #define SIGP_SET_PREFIX 13 | 14 | #define SIGP_SET_PREFIX 13 |
14 | #define SIGP_STORE_STATUS_AT_ADDRESS 14 | 15 | #define SIGP_STORE_STATUS_AT_ADDRESS 14 |
15 | #define SIGP_SET_ARCHITECTURE 18 | 16 | #define SIGP_SET_ARCHITECTURE 18 |
diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c index 0f961a1c64b3..8b9ccf02a2c5 100644 --- a/arch/s390/kvm/gaccess.c +++ b/arch/s390/kvm/gaccess.c | |||
@@ -207,8 +207,6 @@ union raddress { | |||
207 | unsigned long pfra : 52; /* Page-Frame Real Address */ | 207 | unsigned long pfra : 52; /* Page-Frame Real Address */ |
208 | }; | 208 | }; |
209 | 209 | ||
210 | static int ipte_lock_count; | ||
211 | static DEFINE_MUTEX(ipte_mutex); | ||
212 | 210 | ||
213 | int ipte_lock_held(struct kvm_vcpu *vcpu) | 211 | int ipte_lock_held(struct kvm_vcpu *vcpu) |
214 | { | 212 | { |
@@ -216,47 +214,51 @@ int ipte_lock_held(struct kvm_vcpu *vcpu) | |||
216 | 214 | ||
217 | if (vcpu->arch.sie_block->eca & 1) | 215 | if (vcpu->arch.sie_block->eca & 1) |
218 | return ic->kh != 0; | 216 | return ic->kh != 0; |
219 | return ipte_lock_count != 0; | 217 | return vcpu->kvm->arch.ipte_lock_count != 0; |
220 | } | 218 | } |
221 | 219 | ||
222 | static void ipte_lock_simple(struct kvm_vcpu *vcpu) | 220 | static void ipte_lock_simple(struct kvm_vcpu *vcpu) |
223 | { | 221 | { |
224 | union ipte_control old, new, *ic; | 222 | union ipte_control old, new, *ic; |
225 | 223 | ||
226 | mutex_lock(&ipte_mutex); | 224 | mutex_lock(&vcpu->kvm->arch.ipte_mutex); |
227 | ipte_lock_count++; | 225 | vcpu->kvm->arch.ipte_lock_count++; |
228 | if (ipte_lock_count > 1) | 226 | if (vcpu->kvm->arch.ipte_lock_count > 1) |
229 | goto out; | 227 | goto out; |
230 | ic = &vcpu->kvm->arch.sca->ipte_control; | 228 | ic = &vcpu->kvm->arch.sca->ipte_control; |
231 | do { | 229 | do { |
232 | old = ACCESS_ONCE(*ic); | 230 | old = *ic; |
231 | barrier(); | ||
233 | while (old.k) { | 232 | while (old.k) { |
234 | cond_resched(); | 233 | cond_resched(); |
235 | old = ACCESS_ONCE(*ic); | 234 | old = *ic; |
235 | barrier(); | ||
236 | } | 236 | } |
237 | new = old; | 237 | new = old; |
238 | new.k = 1; | 238 | new.k = 1; |
239 | } while (cmpxchg(&ic->val, old.val, new.val) != old.val); | 239 | } while (cmpxchg(&ic->val, old.val, new.val) != old.val); |
240 | out: | 240 | out: |
241 | mutex_unlock(&ipte_mutex); | 241 | mutex_unlock(&vcpu->kvm->arch.ipte_mutex); |
242 | } | 242 | } |
243 | 243 | ||
244 | static void ipte_unlock_simple(struct kvm_vcpu *vcpu) | 244 | static void ipte_unlock_simple(struct kvm_vcpu *vcpu) |
245 | { | 245 | { |
246 | union ipte_control old, new, *ic; | 246 | union ipte_control old, new, *ic; |
247 | 247 | ||
248 | mutex_lock(&ipte_mutex); | 248 | mutex_lock(&vcpu->kvm->arch.ipte_mutex); |
249 | ipte_lock_count--; | 249 | vcpu->kvm->arch.ipte_lock_count--; |
250 | if (ipte_lock_count) | 250 | if (vcpu->kvm->arch.ipte_lock_count) |
251 | goto out; | 251 | goto out; |
252 | ic = &vcpu->kvm->arch.sca->ipte_control; | 252 | ic = &vcpu->kvm->arch.sca->ipte_control; |
253 | do { | 253 | do { |
254 | new = old = ACCESS_ONCE(*ic); | 254 | old = *ic; |
255 | barrier(); | ||
256 | new = old; | ||
255 | new.k = 0; | 257 | new.k = 0; |
256 | } while (cmpxchg(&ic->val, old.val, new.val) != old.val); | 258 | } while (cmpxchg(&ic->val, old.val, new.val) != old.val); |
257 | wake_up(&vcpu->kvm->arch.ipte_wq); | 259 | wake_up(&vcpu->kvm->arch.ipte_wq); |
258 | out: | 260 | out: |
259 | mutex_unlock(&ipte_mutex); | 261 | mutex_unlock(&vcpu->kvm->arch.ipte_mutex); |
260 | } | 262 | } |
261 | 263 | ||
262 | static void ipte_lock_siif(struct kvm_vcpu *vcpu) | 264 | static void ipte_lock_siif(struct kvm_vcpu *vcpu) |
@@ -265,10 +267,12 @@ static void ipte_lock_siif(struct kvm_vcpu *vcpu) | |||
265 | 267 | ||
266 | ic = &vcpu->kvm->arch.sca->ipte_control; | 268 | ic = &vcpu->kvm->arch.sca->ipte_control; |
267 | do { | 269 | do { |
268 | old = ACCESS_ONCE(*ic); | 270 | old = *ic; |
271 | barrier(); | ||
269 | while (old.kg) { | 272 | while (old.kg) { |
270 | cond_resched(); | 273 | cond_resched(); |
271 | old = ACCESS_ONCE(*ic); | 274 | old = *ic; |
275 | barrier(); | ||
272 | } | 276 | } |
273 | new = old; | 277 | new = old; |
274 | new.k = 1; | 278 | new.k = 1; |
@@ -282,7 +286,9 @@ static void ipte_unlock_siif(struct kvm_vcpu *vcpu) | |||
282 | 286 | ||
283 | ic = &vcpu->kvm->arch.sca->ipte_control; | 287 | ic = &vcpu->kvm->arch.sca->ipte_control; |
284 | do { | 288 | do { |
285 | new = old = ACCESS_ONCE(*ic); | 289 | old = *ic; |
290 | barrier(); | ||
291 | new = old; | ||
286 | new.kh--; | 292 | new.kh--; |
287 | if (!new.kh) | 293 | if (!new.kh) |
288 | new.k = 0; | 294 | new.k = 0; |
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c index eaf46291d361..81c77ab8102e 100644 --- a/arch/s390/kvm/intercept.c +++ b/arch/s390/kvm/intercept.c | |||
@@ -38,6 +38,19 @@ static const intercept_handler_t instruction_handlers[256] = { | |||
38 | [0xeb] = kvm_s390_handle_eb, | 38 | [0xeb] = kvm_s390_handle_eb, |
39 | }; | 39 | }; |
40 | 40 | ||
41 | void kvm_s390_rewind_psw(struct kvm_vcpu *vcpu, int ilc) | ||
42 | { | ||
43 | struct kvm_s390_sie_block *sie_block = vcpu->arch.sie_block; | ||
44 | |||
45 | /* Use the length of the EXECUTE instruction if necessary */ | ||
46 | if (sie_block->icptstatus & 1) { | ||
47 | ilc = (sie_block->icptstatus >> 4) & 0x6; | ||
48 | if (!ilc) | ||
49 | ilc = 4; | ||
50 | } | ||
51 | sie_block->gpsw.addr = __rewind_psw(sie_block->gpsw, ilc); | ||
52 | } | ||
53 | |||
41 | static int handle_noop(struct kvm_vcpu *vcpu) | 54 | static int handle_noop(struct kvm_vcpu *vcpu) |
42 | { | 55 | { |
43 | switch (vcpu->arch.sie_block->icptcode) { | 56 | switch (vcpu->arch.sie_block->icptcode) { |
@@ -244,7 +257,7 @@ static int handle_instruction_and_prog(struct kvm_vcpu *vcpu) | |||
244 | static int handle_external_interrupt(struct kvm_vcpu *vcpu) | 257 | static int handle_external_interrupt(struct kvm_vcpu *vcpu) |
245 | { | 258 | { |
246 | u16 eic = vcpu->arch.sie_block->eic; | 259 | u16 eic = vcpu->arch.sie_block->eic; |
247 | struct kvm_s390_interrupt irq; | 260 | struct kvm_s390_irq irq; |
248 | psw_t newpsw; | 261 | psw_t newpsw; |
249 | int rc; | 262 | int rc; |
250 | 263 | ||
@@ -269,7 +282,7 @@ static int handle_external_interrupt(struct kvm_vcpu *vcpu) | |||
269 | if (kvm_s390_si_ext_call_pending(vcpu)) | 282 | if (kvm_s390_si_ext_call_pending(vcpu)) |
270 | return 0; | 283 | return 0; |
271 | irq.type = KVM_S390_INT_EXTERNAL_CALL; | 284 | irq.type = KVM_S390_INT_EXTERNAL_CALL; |
272 | irq.parm = vcpu->arch.sie_block->extcpuaddr; | 285 | irq.u.extcall.code = vcpu->arch.sie_block->extcpuaddr; |
273 | break; | 286 | break; |
274 | default: | 287 | default: |
275 | return -EOPNOTSUPP; | 288 | return -EOPNOTSUPP; |
@@ -288,7 +301,6 @@ static int handle_external_interrupt(struct kvm_vcpu *vcpu) | |||
288 | */ | 301 | */ |
289 | static int handle_mvpg_pei(struct kvm_vcpu *vcpu) | 302 | static int handle_mvpg_pei(struct kvm_vcpu *vcpu) |
290 | { | 303 | { |
291 | psw_t *psw = &vcpu->arch.sie_block->gpsw; | ||
292 | unsigned long srcaddr, dstaddr; | 304 | unsigned long srcaddr, dstaddr; |
293 | int reg1, reg2, rc; | 305 | int reg1, reg2, rc; |
294 | 306 | ||
@@ -310,7 +322,7 @@ static int handle_mvpg_pei(struct kvm_vcpu *vcpu) | |||
310 | if (rc != 0) | 322 | if (rc != 0) |
311 | return rc; | 323 | return rc; |
312 | 324 | ||
313 | psw->addr = __rewind_psw(*psw, 4); | 325 | kvm_s390_rewind_psw(vcpu, 4); |
314 | 326 | ||
315 | return 0; | 327 | return 0; |
316 | } | 328 | } |
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index a39838457f01..f00f31e66cd8 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/mmu_context.h> | 16 | #include <linux/mmu_context.h> |
17 | #include <linux/signal.h> | 17 | #include <linux/signal.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/bitmap.h> | ||
19 | #include <asm/asm-offsets.h> | 20 | #include <asm/asm-offsets.h> |
20 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
21 | #include "kvm-s390.h" | 22 | #include "kvm-s390.h" |
@@ -27,8 +28,8 @@ | |||
27 | #define IOINT_CSSID_MASK 0x03fc0000 | 28 | #define IOINT_CSSID_MASK 0x03fc0000 |
28 | #define IOINT_AI_MASK 0x04000000 | 29 | #define IOINT_AI_MASK 0x04000000 |
29 | #define PFAULT_INIT 0x0600 | 30 | #define PFAULT_INIT 0x0600 |
30 | 31 | #define PFAULT_DONE 0x0680 | |
31 | static int __must_check deliver_ckc_interrupt(struct kvm_vcpu *vcpu); | 32 | #define VIRTIO_PARAM 0x0d00 |
32 | 33 | ||
33 | static int is_ioint(u64 type) | 34 | static int is_ioint(u64 type) |
34 | { | 35 | { |
@@ -136,6 +137,31 @@ static int __must_check __interrupt_is_deliverable(struct kvm_vcpu *vcpu, | |||
136 | return 0; | 137 | return 0; |
137 | } | 138 | } |
138 | 139 | ||
140 | static inline unsigned long pending_local_irqs(struct kvm_vcpu *vcpu) | ||
141 | { | ||
142 | return vcpu->arch.local_int.pending_irqs; | ||
143 | } | ||
144 | |||
145 | static unsigned long deliverable_local_irqs(struct kvm_vcpu *vcpu) | ||
146 | { | ||
147 | unsigned long active_mask = pending_local_irqs(vcpu); | ||
148 | |||
149 | if (psw_extint_disabled(vcpu)) | ||
150 | active_mask &= ~IRQ_PEND_EXT_MASK; | ||
151 | if (!(vcpu->arch.sie_block->gcr[0] & 0x2000ul)) | ||
152 | __clear_bit(IRQ_PEND_EXT_EXTERNAL, &active_mask); | ||
153 | if (!(vcpu->arch.sie_block->gcr[0] & 0x4000ul)) | ||
154 | __clear_bit(IRQ_PEND_EXT_EMERGENCY, &active_mask); | ||
155 | if (!(vcpu->arch.sie_block->gcr[0] & 0x800ul)) | ||
156 | __clear_bit(IRQ_PEND_EXT_CLOCK_COMP, &active_mask); | ||
157 | if (!(vcpu->arch.sie_block->gcr[0] & 0x400ul)) | ||
158 | __clear_bit(IRQ_PEND_EXT_CPU_TIMER, &active_mask); | ||
159 | if (psw_mchk_disabled(vcpu)) | ||
160 | active_mask &= ~IRQ_PEND_MCHK_MASK; | ||
161 | |||
162 | return active_mask; | ||
163 | } | ||
164 | |||
139 | static void __set_cpu_idle(struct kvm_vcpu *vcpu) | 165 | static void __set_cpu_idle(struct kvm_vcpu *vcpu) |
140 | { | 166 | { |
141 | atomic_set_mask(CPUSTAT_WAIT, &vcpu->arch.sie_block->cpuflags); | 167 | atomic_set_mask(CPUSTAT_WAIT, &vcpu->arch.sie_block->cpuflags); |
@@ -170,26 +196,45 @@ static void __set_cpuflag(struct kvm_vcpu *vcpu, u32 flag) | |||
170 | atomic_set_mask(flag, &vcpu->arch.sie_block->cpuflags); | 196 | atomic_set_mask(flag, &vcpu->arch.sie_block->cpuflags); |
171 | } | 197 | } |
172 | 198 | ||
199 | static void set_intercept_indicators_ext(struct kvm_vcpu *vcpu) | ||
200 | { | ||
201 | if (!(pending_local_irqs(vcpu) & IRQ_PEND_EXT_MASK)) | ||
202 | return; | ||
203 | if (psw_extint_disabled(vcpu)) | ||
204 | __set_cpuflag(vcpu, CPUSTAT_EXT_INT); | ||
205 | else | ||
206 | vcpu->arch.sie_block->lctl |= LCTL_CR0; | ||
207 | } | ||
208 | |||
209 | static void set_intercept_indicators_mchk(struct kvm_vcpu *vcpu) | ||
210 | { | ||
211 | if (!(pending_local_irqs(vcpu) & IRQ_PEND_MCHK_MASK)) | ||
212 | return; | ||
213 | if (psw_mchk_disabled(vcpu)) | ||
214 | vcpu->arch.sie_block->ictl |= ICTL_LPSW; | ||
215 | else | ||
216 | vcpu->arch.sie_block->lctl |= LCTL_CR14; | ||
217 | } | ||
218 | |||
219 | /* Set interception request for non-deliverable local interrupts */ | ||
220 | static void set_intercept_indicators_local(struct kvm_vcpu *vcpu) | ||
221 | { | ||
222 | set_intercept_indicators_ext(vcpu); | ||
223 | set_intercept_indicators_mchk(vcpu); | ||
224 | } | ||
225 | |||
173 | static void __set_intercept_indicator(struct kvm_vcpu *vcpu, | 226 | static void __set_intercept_indicator(struct kvm_vcpu *vcpu, |
174 | struct kvm_s390_interrupt_info *inti) | 227 | struct kvm_s390_interrupt_info *inti) |
175 | { | 228 | { |
176 | switch (inti->type) { | 229 | switch (inti->type) { |
177 | case KVM_S390_INT_EXTERNAL_CALL: | ||
178 | case KVM_S390_INT_EMERGENCY: | ||
179 | case KVM_S390_INT_SERVICE: | 230 | case KVM_S390_INT_SERVICE: |
180 | case KVM_S390_INT_PFAULT_INIT: | ||
181 | case KVM_S390_INT_PFAULT_DONE: | 231 | case KVM_S390_INT_PFAULT_DONE: |
182 | case KVM_S390_INT_VIRTIO: | 232 | case KVM_S390_INT_VIRTIO: |
183 | case KVM_S390_INT_CLOCK_COMP: | ||
184 | case KVM_S390_INT_CPU_TIMER: | ||
185 | if (psw_extint_disabled(vcpu)) | 233 | if (psw_extint_disabled(vcpu)) |
186 | __set_cpuflag(vcpu, CPUSTAT_EXT_INT); | 234 | __set_cpuflag(vcpu, CPUSTAT_EXT_INT); |
187 | else | 235 | else |
188 | vcpu->arch.sie_block->lctl |= LCTL_CR0; | 236 | vcpu->arch.sie_block->lctl |= LCTL_CR0; |
189 | break; | 237 | break; |
190 | case KVM_S390_SIGP_STOP: | ||
191 | __set_cpuflag(vcpu, CPUSTAT_STOP_INT); | ||
192 | break; | ||
193 | case KVM_S390_MCHK: | 238 | case KVM_S390_MCHK: |
194 | if (psw_mchk_disabled(vcpu)) | 239 | if (psw_mchk_disabled(vcpu)) |
195 | vcpu->arch.sie_block->ictl |= ICTL_LPSW; | 240 | vcpu->arch.sie_block->ictl |= ICTL_LPSW; |
@@ -226,13 +271,236 @@ static u16 get_ilc(struct kvm_vcpu *vcpu) | |||
226 | } | 271 | } |
227 | } | 272 | } |
228 | 273 | ||
229 | static int __must_check __deliver_prog_irq(struct kvm_vcpu *vcpu, | 274 | static int __must_check __deliver_cpu_timer(struct kvm_vcpu *vcpu) |
230 | struct kvm_s390_pgm_info *pgm_info) | 275 | { |
276 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
277 | int rc; | ||
278 | |||
279 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_CPU_TIMER, | ||
280 | 0, 0); | ||
281 | |||
282 | rc = put_guest_lc(vcpu, EXT_IRQ_CPU_TIMER, | ||
283 | (u16 *)__LC_EXT_INT_CODE); | ||
284 | rc |= put_guest_lc(vcpu, 0, (u16 *)__LC_EXT_CPU_ADDR); | ||
285 | rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, | ||
286 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
287 | rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, | ||
288 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
289 | clear_bit(IRQ_PEND_EXT_CPU_TIMER, &li->pending_irqs); | ||
290 | return rc ? -EFAULT : 0; | ||
291 | } | ||
292 | |||
293 | static int __must_check __deliver_ckc(struct kvm_vcpu *vcpu) | ||
294 | { | ||
295 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
296 | int rc; | ||
297 | |||
298 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_CLOCK_COMP, | ||
299 | 0, 0); | ||
300 | |||
301 | rc = put_guest_lc(vcpu, EXT_IRQ_CLK_COMP, | ||
302 | (u16 __user *)__LC_EXT_INT_CODE); | ||
303 | rc |= put_guest_lc(vcpu, 0, (u16 *)__LC_EXT_CPU_ADDR); | ||
304 | rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, | ||
305 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
306 | rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, | ||
307 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
308 | clear_bit(IRQ_PEND_EXT_CLOCK_COMP, &li->pending_irqs); | ||
309 | return rc ? -EFAULT : 0; | ||
310 | } | ||
311 | |||
312 | static int __must_check __deliver_pfault_init(struct kvm_vcpu *vcpu) | ||
313 | { | ||
314 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
315 | struct kvm_s390_ext_info ext; | ||
316 | int rc; | ||
317 | |||
318 | spin_lock(&li->lock); | ||
319 | ext = li->irq.ext; | ||
320 | clear_bit(IRQ_PEND_PFAULT_INIT, &li->pending_irqs); | ||
321 | li->irq.ext.ext_params2 = 0; | ||
322 | spin_unlock(&li->lock); | ||
323 | |||
324 | VCPU_EVENT(vcpu, 4, "interrupt: pfault init parm:%x,parm64:%llx", | ||
325 | 0, ext.ext_params2); | ||
326 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, | ||
327 | KVM_S390_INT_PFAULT_INIT, | ||
328 | 0, ext.ext_params2); | ||
329 | |||
330 | rc = put_guest_lc(vcpu, EXT_IRQ_CP_SERVICE, (u16 *) __LC_EXT_INT_CODE); | ||
331 | rc |= put_guest_lc(vcpu, PFAULT_INIT, (u16 *) __LC_EXT_CPU_ADDR); | ||
332 | rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, | ||
333 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
334 | rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, | ||
335 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
336 | rc |= put_guest_lc(vcpu, ext.ext_params2, (u64 *) __LC_EXT_PARAMS2); | ||
337 | return rc ? -EFAULT : 0; | ||
338 | } | ||
339 | |||
340 | static int __must_check __deliver_machine_check(struct kvm_vcpu *vcpu) | ||
341 | { | ||
342 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
343 | struct kvm_s390_mchk_info mchk; | ||
344 | int rc; | ||
345 | |||
346 | spin_lock(&li->lock); | ||
347 | mchk = li->irq.mchk; | ||
348 | /* | ||
349 | * If there was an exigent machine check pending, then any repressible | ||
350 | * machine checks that might have been pending are indicated along | ||
351 | * with it, so always clear both bits | ||
352 | */ | ||
353 | clear_bit(IRQ_PEND_MCHK_EX, &li->pending_irqs); | ||
354 | clear_bit(IRQ_PEND_MCHK_REP, &li->pending_irqs); | ||
355 | memset(&li->irq.mchk, 0, sizeof(mchk)); | ||
356 | spin_unlock(&li->lock); | ||
357 | |||
358 | VCPU_EVENT(vcpu, 4, "interrupt: machine check mcic=%llx", | ||
359 | mchk.mcic); | ||
360 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_MCHK, | ||
361 | mchk.cr14, mchk.mcic); | ||
362 | |||
363 | rc = kvm_s390_vcpu_store_status(vcpu, KVM_S390_STORE_STATUS_PREFIXED); | ||
364 | rc |= put_guest_lc(vcpu, mchk.mcic, | ||
365 | (u64 __user *) __LC_MCCK_CODE); | ||
366 | rc |= put_guest_lc(vcpu, mchk.failing_storage_address, | ||
367 | (u64 __user *) __LC_MCCK_FAIL_STOR_ADDR); | ||
368 | rc |= write_guest_lc(vcpu, __LC_PSW_SAVE_AREA, | ||
369 | &mchk.fixed_logout, sizeof(mchk.fixed_logout)); | ||
370 | rc |= write_guest_lc(vcpu, __LC_MCK_OLD_PSW, | ||
371 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
372 | rc |= read_guest_lc(vcpu, __LC_MCK_NEW_PSW, | ||
373 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
374 | return rc ? -EFAULT : 0; | ||
375 | } | ||
376 | |||
377 | static int __must_check __deliver_restart(struct kvm_vcpu *vcpu) | ||
378 | { | ||
379 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
380 | int rc; | ||
381 | |||
382 | VCPU_EVENT(vcpu, 4, "%s", "interrupt: cpu restart"); | ||
383 | vcpu->stat.deliver_restart_signal++; | ||
384 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_RESTART, 0, 0); | ||
385 | |||
386 | rc = write_guest_lc(vcpu, | ||
387 | offsetof(struct _lowcore, restart_old_psw), | ||
388 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
389 | rc |= read_guest_lc(vcpu, offsetof(struct _lowcore, restart_psw), | ||
390 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
391 | clear_bit(IRQ_PEND_RESTART, &li->pending_irqs); | ||
392 | return rc ? -EFAULT : 0; | ||
393 | } | ||
394 | |||
395 | static int __must_check __deliver_stop(struct kvm_vcpu *vcpu) | ||
396 | { | ||
397 | VCPU_EVENT(vcpu, 4, "%s", "interrupt: cpu stop"); | ||
398 | vcpu->stat.deliver_stop_signal++; | ||
399 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_SIGP_STOP, | ||
400 | 0, 0); | ||
401 | |||
402 | __set_cpuflag(vcpu, CPUSTAT_STOP_INT); | ||
403 | clear_bit(IRQ_PEND_SIGP_STOP, &vcpu->arch.local_int.pending_irqs); | ||
404 | return 0; | ||
405 | } | ||
406 | |||
407 | static int __must_check __deliver_set_prefix(struct kvm_vcpu *vcpu) | ||
408 | { | ||
409 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
410 | struct kvm_s390_prefix_info prefix; | ||
411 | |||
412 | spin_lock(&li->lock); | ||
413 | prefix = li->irq.prefix; | ||
414 | li->irq.prefix.address = 0; | ||
415 | clear_bit(IRQ_PEND_SET_PREFIX, &li->pending_irqs); | ||
416 | spin_unlock(&li->lock); | ||
417 | |||
418 | VCPU_EVENT(vcpu, 4, "interrupt: set prefix to %x", prefix.address); | ||
419 | vcpu->stat.deliver_prefix_signal++; | ||
420 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, | ||
421 | KVM_S390_SIGP_SET_PREFIX, | ||
422 | prefix.address, 0); | ||
423 | |||
424 | kvm_s390_set_prefix(vcpu, prefix.address); | ||
425 | return 0; | ||
426 | } | ||
427 | |||
428 | static int __must_check __deliver_emergency_signal(struct kvm_vcpu *vcpu) | ||
429 | { | ||
430 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
431 | int rc; | ||
432 | int cpu_addr; | ||
433 | |||
434 | spin_lock(&li->lock); | ||
435 | cpu_addr = find_first_bit(li->sigp_emerg_pending, KVM_MAX_VCPUS); | ||
436 | clear_bit(cpu_addr, li->sigp_emerg_pending); | ||
437 | if (bitmap_empty(li->sigp_emerg_pending, KVM_MAX_VCPUS)) | ||
438 | clear_bit(IRQ_PEND_EXT_EMERGENCY, &li->pending_irqs); | ||
439 | spin_unlock(&li->lock); | ||
440 | |||
441 | VCPU_EVENT(vcpu, 4, "%s", "interrupt: sigp emerg"); | ||
442 | vcpu->stat.deliver_emergency_signal++; | ||
443 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_EMERGENCY, | ||
444 | cpu_addr, 0); | ||
445 | |||
446 | rc = put_guest_lc(vcpu, EXT_IRQ_EMERGENCY_SIG, | ||
447 | (u16 *)__LC_EXT_INT_CODE); | ||
448 | rc |= put_guest_lc(vcpu, cpu_addr, (u16 *)__LC_EXT_CPU_ADDR); | ||
449 | rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, | ||
450 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
451 | rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, | ||
452 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
453 | return rc ? -EFAULT : 0; | ||
454 | } | ||
455 | |||
456 | static int __must_check __deliver_external_call(struct kvm_vcpu *vcpu) | ||
457 | { | ||
458 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
459 | struct kvm_s390_extcall_info extcall; | ||
460 | int rc; | ||
461 | |||
462 | spin_lock(&li->lock); | ||
463 | extcall = li->irq.extcall; | ||
464 | li->irq.extcall.code = 0; | ||
465 | clear_bit(IRQ_PEND_EXT_EXTERNAL, &li->pending_irqs); | ||
466 | spin_unlock(&li->lock); | ||
467 | |||
468 | VCPU_EVENT(vcpu, 4, "%s", "interrupt: sigp ext call"); | ||
469 | vcpu->stat.deliver_external_call++; | ||
470 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, | ||
471 | KVM_S390_INT_EXTERNAL_CALL, | ||
472 | extcall.code, 0); | ||
473 | |||
474 | rc = put_guest_lc(vcpu, EXT_IRQ_EXTERNAL_CALL, | ||
475 | (u16 *)__LC_EXT_INT_CODE); | ||
476 | rc |= put_guest_lc(vcpu, extcall.code, (u16 *)__LC_EXT_CPU_ADDR); | ||
477 | rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, | ||
478 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
479 | rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, &vcpu->arch.sie_block->gpsw, | ||
480 | sizeof(psw_t)); | ||
481 | return rc ? -EFAULT : 0; | ||
482 | } | ||
483 | |||
484 | static int __must_check __deliver_prog(struct kvm_vcpu *vcpu) | ||
231 | { | 485 | { |
486 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
487 | struct kvm_s390_pgm_info pgm_info; | ||
232 | int rc = 0; | 488 | int rc = 0; |
233 | u16 ilc = get_ilc(vcpu); | 489 | u16 ilc = get_ilc(vcpu); |
234 | 490 | ||
235 | switch (pgm_info->code & ~PGM_PER) { | 491 | spin_lock(&li->lock); |
492 | pgm_info = li->irq.pgm; | ||
493 | clear_bit(IRQ_PEND_PROG, &li->pending_irqs); | ||
494 | memset(&li->irq.pgm, 0, sizeof(pgm_info)); | ||
495 | spin_unlock(&li->lock); | ||
496 | |||
497 | VCPU_EVENT(vcpu, 4, "interrupt: pgm check code:%x, ilc:%x", | ||
498 | pgm_info.code, ilc); | ||
499 | vcpu->stat.deliver_program_int++; | ||
500 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_PROGRAM_INT, | ||
501 | pgm_info.code, 0); | ||
502 | |||
503 | switch (pgm_info.code & ~PGM_PER) { | ||
236 | case PGM_AFX_TRANSLATION: | 504 | case PGM_AFX_TRANSLATION: |
237 | case PGM_ASX_TRANSLATION: | 505 | case PGM_ASX_TRANSLATION: |
238 | case PGM_EX_TRANSLATION: | 506 | case PGM_EX_TRANSLATION: |
@@ -243,7 +511,7 @@ static int __must_check __deliver_prog_irq(struct kvm_vcpu *vcpu, | |||
243 | case PGM_PRIMARY_AUTHORITY: | 511 | case PGM_PRIMARY_AUTHORITY: |
244 | case PGM_SECONDARY_AUTHORITY: | 512 | case PGM_SECONDARY_AUTHORITY: |
245 | case PGM_SPACE_SWITCH: | 513 | case PGM_SPACE_SWITCH: |
246 | rc = put_guest_lc(vcpu, pgm_info->trans_exc_code, | 514 | rc = put_guest_lc(vcpu, pgm_info.trans_exc_code, |
247 | (u64 *)__LC_TRANS_EXC_CODE); | 515 | (u64 *)__LC_TRANS_EXC_CODE); |
248 | break; | 516 | break; |
249 | case PGM_ALEN_TRANSLATION: | 517 | case PGM_ALEN_TRANSLATION: |
@@ -252,7 +520,7 @@ static int __must_check __deliver_prog_irq(struct kvm_vcpu *vcpu, | |||
252 | case PGM_ASTE_SEQUENCE: | 520 | case PGM_ASTE_SEQUENCE: |
253 | case PGM_ASTE_VALIDITY: | 521 | case PGM_ASTE_VALIDITY: |
254 | case PGM_EXTENDED_AUTHORITY: | 522 | case PGM_EXTENDED_AUTHORITY: |
255 | rc = put_guest_lc(vcpu, pgm_info->exc_access_id, | 523 | rc = put_guest_lc(vcpu, pgm_info.exc_access_id, |
256 | (u8 *)__LC_EXC_ACCESS_ID); | 524 | (u8 *)__LC_EXC_ACCESS_ID); |
257 | break; | 525 | break; |
258 | case PGM_ASCE_TYPE: | 526 | case PGM_ASCE_TYPE: |
@@ -261,247 +529,208 @@ static int __must_check __deliver_prog_irq(struct kvm_vcpu *vcpu, | |||
261 | case PGM_REGION_SECOND_TRANS: | 529 | case PGM_REGION_SECOND_TRANS: |
262 | case PGM_REGION_THIRD_TRANS: | 530 | case PGM_REGION_THIRD_TRANS: |
263 | case PGM_SEGMENT_TRANSLATION: | 531 | case PGM_SEGMENT_TRANSLATION: |
264 | rc = put_guest_lc(vcpu, pgm_info->trans_exc_code, | 532 | rc = put_guest_lc(vcpu, pgm_info.trans_exc_code, |
265 | (u64 *)__LC_TRANS_EXC_CODE); | 533 | (u64 *)__LC_TRANS_EXC_CODE); |
266 | rc |= put_guest_lc(vcpu, pgm_info->exc_access_id, | 534 | rc |= put_guest_lc(vcpu, pgm_info.exc_access_id, |
267 | (u8 *)__LC_EXC_ACCESS_ID); | 535 | (u8 *)__LC_EXC_ACCESS_ID); |
268 | rc |= put_guest_lc(vcpu, pgm_info->op_access_id, | 536 | rc |= put_guest_lc(vcpu, pgm_info.op_access_id, |
269 | (u8 *)__LC_OP_ACCESS_ID); | 537 | (u8 *)__LC_OP_ACCESS_ID); |
270 | break; | 538 | break; |
271 | case PGM_MONITOR: | 539 | case PGM_MONITOR: |
272 | rc = put_guest_lc(vcpu, pgm_info->mon_class_nr, | 540 | rc = put_guest_lc(vcpu, pgm_info.mon_class_nr, |
273 | (u64 *)__LC_MON_CLASS_NR); | 541 | (u16 *)__LC_MON_CLASS_NR); |
274 | rc |= put_guest_lc(vcpu, pgm_info->mon_code, | 542 | rc |= put_guest_lc(vcpu, pgm_info.mon_code, |
275 | (u64 *)__LC_MON_CODE); | 543 | (u64 *)__LC_MON_CODE); |
276 | break; | 544 | break; |
277 | case PGM_DATA: | 545 | case PGM_DATA: |
278 | rc = put_guest_lc(vcpu, pgm_info->data_exc_code, | 546 | rc = put_guest_lc(vcpu, pgm_info.data_exc_code, |
279 | (u32 *)__LC_DATA_EXC_CODE); | 547 | (u32 *)__LC_DATA_EXC_CODE); |
280 | break; | 548 | break; |
281 | case PGM_PROTECTION: | 549 | case PGM_PROTECTION: |
282 | rc = put_guest_lc(vcpu, pgm_info->trans_exc_code, | 550 | rc = put_guest_lc(vcpu, pgm_info.trans_exc_code, |
283 | (u64 *)__LC_TRANS_EXC_CODE); | 551 | (u64 *)__LC_TRANS_EXC_CODE); |
284 | rc |= put_guest_lc(vcpu, pgm_info->exc_access_id, | 552 | rc |= put_guest_lc(vcpu, pgm_info.exc_access_id, |
285 | (u8 *)__LC_EXC_ACCESS_ID); | 553 | (u8 *)__LC_EXC_ACCESS_ID); |
286 | break; | 554 | break; |
287 | } | 555 | } |
288 | 556 | ||
289 | if (pgm_info->code & PGM_PER) { | 557 | if (pgm_info.code & PGM_PER) { |
290 | rc |= put_guest_lc(vcpu, pgm_info->per_code, | 558 | rc |= put_guest_lc(vcpu, pgm_info.per_code, |
291 | (u8 *) __LC_PER_CODE); | 559 | (u8 *) __LC_PER_CODE); |
292 | rc |= put_guest_lc(vcpu, pgm_info->per_atmid, | 560 | rc |= put_guest_lc(vcpu, pgm_info.per_atmid, |
293 | (u8 *)__LC_PER_ATMID); | 561 | (u8 *)__LC_PER_ATMID); |
294 | rc |= put_guest_lc(vcpu, pgm_info->per_address, | 562 | rc |= put_guest_lc(vcpu, pgm_info.per_address, |
295 | (u64 *) __LC_PER_ADDRESS); | 563 | (u64 *) __LC_PER_ADDRESS); |
296 | rc |= put_guest_lc(vcpu, pgm_info->per_access_id, | 564 | rc |= put_guest_lc(vcpu, pgm_info.per_access_id, |
297 | (u8 *) __LC_PER_ACCESS_ID); | 565 | (u8 *) __LC_PER_ACCESS_ID); |
298 | } | 566 | } |
299 | 567 | ||
300 | rc |= put_guest_lc(vcpu, ilc, (u16 *) __LC_PGM_ILC); | 568 | rc |= put_guest_lc(vcpu, ilc, (u16 *) __LC_PGM_ILC); |
301 | rc |= put_guest_lc(vcpu, pgm_info->code, | 569 | rc |= put_guest_lc(vcpu, pgm_info.code, |
302 | (u16 *)__LC_PGM_INT_CODE); | 570 | (u16 *)__LC_PGM_INT_CODE); |
303 | rc |= write_guest_lc(vcpu, __LC_PGM_OLD_PSW, | 571 | rc |= write_guest_lc(vcpu, __LC_PGM_OLD_PSW, |
304 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | 572 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); |
305 | rc |= read_guest_lc(vcpu, __LC_PGM_NEW_PSW, | 573 | rc |= read_guest_lc(vcpu, __LC_PGM_NEW_PSW, |
306 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | 574 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); |
575 | return rc ? -EFAULT : 0; | ||
576 | } | ||
307 | 577 | ||
308 | return rc; | 578 | static int __must_check __deliver_service(struct kvm_vcpu *vcpu, |
579 | struct kvm_s390_interrupt_info *inti) | ||
580 | { | ||
581 | int rc; | ||
582 | |||
583 | VCPU_EVENT(vcpu, 4, "interrupt: sclp parm:%x", | ||
584 | inti->ext.ext_params); | ||
585 | vcpu->stat.deliver_service_signal++; | ||
586 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, | ||
587 | inti->ext.ext_params, 0); | ||
588 | |||
589 | rc = put_guest_lc(vcpu, EXT_IRQ_SERVICE_SIG, (u16 *)__LC_EXT_INT_CODE); | ||
590 | rc |= put_guest_lc(vcpu, 0, (u16 *)__LC_EXT_CPU_ADDR); | ||
591 | rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, | ||
592 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
593 | rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, | ||
594 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
595 | rc |= put_guest_lc(vcpu, inti->ext.ext_params, | ||
596 | (u32 *)__LC_EXT_PARAMS); | ||
597 | return rc ? -EFAULT : 0; | ||
309 | } | 598 | } |
310 | 599 | ||
311 | static int __must_check __do_deliver_interrupt(struct kvm_vcpu *vcpu, | 600 | static int __must_check __deliver_pfault_done(struct kvm_vcpu *vcpu, |
312 | struct kvm_s390_interrupt_info *inti) | 601 | struct kvm_s390_interrupt_info *inti) |
313 | { | 602 | { |
314 | const unsigned short table[] = { 2, 4, 4, 6 }; | 603 | int rc; |
315 | int rc = 0; | 604 | |
605 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, | ||
606 | KVM_S390_INT_PFAULT_DONE, 0, | ||
607 | inti->ext.ext_params2); | ||
608 | |||
609 | rc = put_guest_lc(vcpu, EXT_IRQ_CP_SERVICE, (u16 *)__LC_EXT_INT_CODE); | ||
610 | rc |= put_guest_lc(vcpu, PFAULT_DONE, (u16 *)__LC_EXT_CPU_ADDR); | ||
611 | rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, | ||
612 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
613 | rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, | ||
614 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
615 | rc |= put_guest_lc(vcpu, inti->ext.ext_params2, | ||
616 | (u64 *)__LC_EXT_PARAMS2); | ||
617 | return rc ? -EFAULT : 0; | ||
618 | } | ||
619 | |||
620 | static int __must_check __deliver_virtio(struct kvm_vcpu *vcpu, | ||
621 | struct kvm_s390_interrupt_info *inti) | ||
622 | { | ||
623 | int rc; | ||
624 | |||
625 | VCPU_EVENT(vcpu, 4, "interrupt: virtio parm:%x,parm64:%llx", | ||
626 | inti->ext.ext_params, inti->ext.ext_params2); | ||
627 | vcpu->stat.deliver_virtio_interrupt++; | ||
628 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, | ||
629 | inti->ext.ext_params, | ||
630 | inti->ext.ext_params2); | ||
631 | |||
632 | rc = put_guest_lc(vcpu, EXT_IRQ_CP_SERVICE, (u16 *)__LC_EXT_INT_CODE); | ||
633 | rc |= put_guest_lc(vcpu, VIRTIO_PARAM, (u16 *)__LC_EXT_CPU_ADDR); | ||
634 | rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, | ||
635 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
636 | rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, | ||
637 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
638 | rc |= put_guest_lc(vcpu, inti->ext.ext_params, | ||
639 | (u32 *)__LC_EXT_PARAMS); | ||
640 | rc |= put_guest_lc(vcpu, inti->ext.ext_params2, | ||
641 | (u64 *)__LC_EXT_PARAMS2); | ||
642 | return rc ? -EFAULT : 0; | ||
643 | } | ||
644 | |||
645 | static int __must_check __deliver_io(struct kvm_vcpu *vcpu, | ||
646 | struct kvm_s390_interrupt_info *inti) | ||
647 | { | ||
648 | int rc; | ||
649 | |||
650 | VCPU_EVENT(vcpu, 4, "interrupt: I/O %llx", inti->type); | ||
651 | vcpu->stat.deliver_io_int++; | ||
652 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, | ||
653 | ((__u32)inti->io.subchannel_id << 16) | | ||
654 | inti->io.subchannel_nr, | ||
655 | ((__u64)inti->io.io_int_parm << 32) | | ||
656 | inti->io.io_int_word); | ||
657 | |||
658 | rc = put_guest_lc(vcpu, inti->io.subchannel_id, | ||
659 | (u16 *)__LC_SUBCHANNEL_ID); | ||
660 | rc |= put_guest_lc(vcpu, inti->io.subchannel_nr, | ||
661 | (u16 *)__LC_SUBCHANNEL_NR); | ||
662 | rc |= put_guest_lc(vcpu, inti->io.io_int_parm, | ||
663 | (u32 *)__LC_IO_INT_PARM); | ||
664 | rc |= put_guest_lc(vcpu, inti->io.io_int_word, | ||
665 | (u32 *)__LC_IO_INT_WORD); | ||
666 | rc |= write_guest_lc(vcpu, __LC_IO_OLD_PSW, | ||
667 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
668 | rc |= read_guest_lc(vcpu, __LC_IO_NEW_PSW, | ||
669 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
670 | return rc ? -EFAULT : 0; | ||
671 | } | ||
672 | |||
673 | static int __must_check __deliver_mchk_floating(struct kvm_vcpu *vcpu, | ||
674 | struct kvm_s390_interrupt_info *inti) | ||
675 | { | ||
676 | struct kvm_s390_mchk_info *mchk = &inti->mchk; | ||
677 | int rc; | ||
678 | |||
679 | VCPU_EVENT(vcpu, 4, "interrupt: machine check mcic=%llx", | ||
680 | mchk->mcic); | ||
681 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_MCHK, | ||
682 | mchk->cr14, mchk->mcic); | ||
683 | |||
684 | rc = kvm_s390_vcpu_store_status(vcpu, KVM_S390_STORE_STATUS_PREFIXED); | ||
685 | rc |= put_guest_lc(vcpu, mchk->mcic, | ||
686 | (u64 __user *) __LC_MCCK_CODE); | ||
687 | rc |= put_guest_lc(vcpu, mchk->failing_storage_address, | ||
688 | (u64 __user *) __LC_MCCK_FAIL_STOR_ADDR); | ||
689 | rc |= write_guest_lc(vcpu, __LC_PSW_SAVE_AREA, | ||
690 | &mchk->fixed_logout, sizeof(mchk->fixed_logout)); | ||
691 | rc |= write_guest_lc(vcpu, __LC_MCK_OLD_PSW, | ||
692 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
693 | rc |= read_guest_lc(vcpu, __LC_MCK_NEW_PSW, | ||
694 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
695 | return rc ? -EFAULT : 0; | ||
696 | } | ||
697 | |||
698 | typedef int (*deliver_irq_t)(struct kvm_vcpu *vcpu); | ||
699 | |||
700 | static const deliver_irq_t deliver_irq_funcs[] = { | ||
701 | [IRQ_PEND_MCHK_EX] = __deliver_machine_check, | ||
702 | [IRQ_PEND_PROG] = __deliver_prog, | ||
703 | [IRQ_PEND_EXT_EMERGENCY] = __deliver_emergency_signal, | ||
704 | [IRQ_PEND_EXT_EXTERNAL] = __deliver_external_call, | ||
705 | [IRQ_PEND_EXT_CLOCK_COMP] = __deliver_ckc, | ||
706 | [IRQ_PEND_EXT_CPU_TIMER] = __deliver_cpu_timer, | ||
707 | [IRQ_PEND_RESTART] = __deliver_restart, | ||
708 | [IRQ_PEND_SIGP_STOP] = __deliver_stop, | ||
709 | [IRQ_PEND_SET_PREFIX] = __deliver_set_prefix, | ||
710 | [IRQ_PEND_PFAULT_INIT] = __deliver_pfault_init, | ||
711 | }; | ||
712 | |||
713 | static int __must_check __deliver_floating_interrupt(struct kvm_vcpu *vcpu, | ||
714 | struct kvm_s390_interrupt_info *inti) | ||
715 | { | ||
716 | int rc; | ||
316 | 717 | ||
317 | switch (inti->type) { | 718 | switch (inti->type) { |
318 | case KVM_S390_INT_EMERGENCY: | ||
319 | VCPU_EVENT(vcpu, 4, "%s", "interrupt: sigp emerg"); | ||
320 | vcpu->stat.deliver_emergency_signal++; | ||
321 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, | ||
322 | inti->emerg.code, 0); | ||
323 | rc = put_guest_lc(vcpu, 0x1201, (u16 *)__LC_EXT_INT_CODE); | ||
324 | rc |= put_guest_lc(vcpu, inti->emerg.code, | ||
325 | (u16 *)__LC_EXT_CPU_ADDR); | ||
326 | rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, | ||
327 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
328 | rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, | ||
329 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
330 | break; | ||
331 | case KVM_S390_INT_EXTERNAL_CALL: | ||
332 | VCPU_EVENT(vcpu, 4, "%s", "interrupt: sigp ext call"); | ||
333 | vcpu->stat.deliver_external_call++; | ||
334 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, | ||
335 | inti->extcall.code, 0); | ||
336 | rc = put_guest_lc(vcpu, 0x1202, (u16 *)__LC_EXT_INT_CODE); | ||
337 | rc |= put_guest_lc(vcpu, inti->extcall.code, | ||
338 | (u16 *)__LC_EXT_CPU_ADDR); | ||
339 | rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, | ||
340 | &vcpu->arch.sie_block->gpsw, | ||
341 | sizeof(psw_t)); | ||
342 | rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, | ||
343 | &vcpu->arch.sie_block->gpsw, | ||
344 | sizeof(psw_t)); | ||
345 | break; | ||
346 | case KVM_S390_INT_CLOCK_COMP: | ||
347 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, | ||
348 | inti->ext.ext_params, 0); | ||
349 | rc = deliver_ckc_interrupt(vcpu); | ||
350 | break; | ||
351 | case KVM_S390_INT_CPU_TIMER: | ||
352 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, | ||
353 | inti->ext.ext_params, 0); | ||
354 | rc = put_guest_lc(vcpu, EXT_IRQ_CPU_TIMER, | ||
355 | (u16 *)__LC_EXT_INT_CODE); | ||
356 | rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, | ||
357 | &vcpu->arch.sie_block->gpsw, | ||
358 | sizeof(psw_t)); | ||
359 | rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, | ||
360 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
361 | rc |= put_guest_lc(vcpu, inti->ext.ext_params, | ||
362 | (u32 *)__LC_EXT_PARAMS); | ||
363 | break; | ||
364 | case KVM_S390_INT_SERVICE: | 719 | case KVM_S390_INT_SERVICE: |
365 | VCPU_EVENT(vcpu, 4, "interrupt: sclp parm:%x", | 720 | rc = __deliver_service(vcpu, inti); |
366 | inti->ext.ext_params); | ||
367 | vcpu->stat.deliver_service_signal++; | ||
368 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, | ||
369 | inti->ext.ext_params, 0); | ||
370 | rc = put_guest_lc(vcpu, 0x2401, (u16 *)__LC_EXT_INT_CODE); | ||
371 | rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, | ||
372 | &vcpu->arch.sie_block->gpsw, | ||
373 | sizeof(psw_t)); | ||
374 | rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, | ||
375 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
376 | rc |= put_guest_lc(vcpu, inti->ext.ext_params, | ||
377 | (u32 *)__LC_EXT_PARAMS); | ||
378 | break; | ||
379 | case KVM_S390_INT_PFAULT_INIT: | ||
380 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, 0, | ||
381 | inti->ext.ext_params2); | ||
382 | rc = put_guest_lc(vcpu, EXT_IRQ_CP_SERVICE, | ||
383 | (u16 *) __LC_EXT_INT_CODE); | ||
384 | rc |= put_guest_lc(vcpu, PFAULT_INIT, (u16 *) __LC_EXT_CPU_ADDR); | ||
385 | rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, | ||
386 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
387 | rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, | ||
388 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
389 | rc |= put_guest_lc(vcpu, inti->ext.ext_params2, | ||
390 | (u64 *) __LC_EXT_PARAMS2); | ||
391 | break; | 721 | break; |
392 | case KVM_S390_INT_PFAULT_DONE: | 722 | case KVM_S390_INT_PFAULT_DONE: |
393 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, 0, | 723 | rc = __deliver_pfault_done(vcpu, inti); |
394 | inti->ext.ext_params2); | ||
395 | rc = put_guest_lc(vcpu, 0x2603, (u16 *)__LC_EXT_INT_CODE); | ||
396 | rc |= put_guest_lc(vcpu, 0x0680, (u16 *)__LC_EXT_CPU_ADDR); | ||
397 | rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, | ||
398 | &vcpu->arch.sie_block->gpsw, | ||
399 | sizeof(psw_t)); | ||
400 | rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, | ||
401 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
402 | rc |= put_guest_lc(vcpu, inti->ext.ext_params2, | ||
403 | (u64 *)__LC_EXT_PARAMS2); | ||
404 | break; | 724 | break; |
405 | case KVM_S390_INT_VIRTIO: | 725 | case KVM_S390_INT_VIRTIO: |
406 | VCPU_EVENT(vcpu, 4, "interrupt: virtio parm:%x,parm64:%llx", | 726 | rc = __deliver_virtio(vcpu, inti); |
407 | inti->ext.ext_params, inti->ext.ext_params2); | ||
408 | vcpu->stat.deliver_virtio_interrupt++; | ||
409 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, | ||
410 | inti->ext.ext_params, | ||
411 | inti->ext.ext_params2); | ||
412 | rc = put_guest_lc(vcpu, 0x2603, (u16 *)__LC_EXT_INT_CODE); | ||
413 | rc |= put_guest_lc(vcpu, 0x0d00, (u16 *)__LC_EXT_CPU_ADDR); | ||
414 | rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, | ||
415 | &vcpu->arch.sie_block->gpsw, | ||
416 | sizeof(psw_t)); | ||
417 | rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, | ||
418 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
419 | rc |= put_guest_lc(vcpu, inti->ext.ext_params, | ||
420 | (u32 *)__LC_EXT_PARAMS); | ||
421 | rc |= put_guest_lc(vcpu, inti->ext.ext_params2, | ||
422 | (u64 *)__LC_EXT_PARAMS2); | ||
423 | break; | ||
424 | case KVM_S390_SIGP_STOP: | ||
425 | VCPU_EVENT(vcpu, 4, "%s", "interrupt: cpu stop"); | ||
426 | vcpu->stat.deliver_stop_signal++; | ||
427 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, | ||
428 | 0, 0); | ||
429 | __set_intercept_indicator(vcpu, inti); | ||
430 | break; | ||
431 | |||
432 | case KVM_S390_SIGP_SET_PREFIX: | ||
433 | VCPU_EVENT(vcpu, 4, "interrupt: set prefix to %x", | ||
434 | inti->prefix.address); | ||
435 | vcpu->stat.deliver_prefix_signal++; | ||
436 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, | ||
437 | inti->prefix.address, 0); | ||
438 | kvm_s390_set_prefix(vcpu, inti->prefix.address); | ||
439 | break; | ||
440 | |||
441 | case KVM_S390_RESTART: | ||
442 | VCPU_EVENT(vcpu, 4, "%s", "interrupt: cpu restart"); | ||
443 | vcpu->stat.deliver_restart_signal++; | ||
444 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, | ||
445 | 0, 0); | ||
446 | rc = write_guest_lc(vcpu, | ||
447 | offsetof(struct _lowcore, restart_old_psw), | ||
448 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
449 | rc |= read_guest_lc(vcpu, offsetof(struct _lowcore, restart_psw), | ||
450 | &vcpu->arch.sie_block->gpsw, | ||
451 | sizeof(psw_t)); | ||
452 | break; | 727 | break; |
453 | case KVM_S390_PROGRAM_INT: | ||
454 | VCPU_EVENT(vcpu, 4, "interrupt: pgm check code:%x, ilc:%x", | ||
455 | inti->pgm.code, | ||
456 | table[vcpu->arch.sie_block->ipa >> 14]); | ||
457 | vcpu->stat.deliver_program_int++; | ||
458 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, | ||
459 | inti->pgm.code, 0); | ||
460 | rc = __deliver_prog_irq(vcpu, &inti->pgm); | ||
461 | break; | ||
462 | |||
463 | case KVM_S390_MCHK: | 728 | case KVM_S390_MCHK: |
464 | VCPU_EVENT(vcpu, 4, "interrupt: machine check mcic=%llx", | 729 | rc = __deliver_mchk_floating(vcpu, inti); |
465 | inti->mchk.mcic); | ||
466 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, | ||
467 | inti->mchk.cr14, | ||
468 | inti->mchk.mcic); | ||
469 | rc = kvm_s390_vcpu_store_status(vcpu, | ||
470 | KVM_S390_STORE_STATUS_PREFIXED); | ||
471 | rc |= put_guest_lc(vcpu, inti->mchk.mcic, (u64 *)__LC_MCCK_CODE); | ||
472 | rc |= write_guest_lc(vcpu, __LC_MCK_OLD_PSW, | ||
473 | &vcpu->arch.sie_block->gpsw, | ||
474 | sizeof(psw_t)); | ||
475 | rc |= read_guest_lc(vcpu, __LC_MCK_NEW_PSW, | ||
476 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
477 | break; | 730 | break; |
478 | |||
479 | case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: | 731 | case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: |
480 | { | 732 | rc = __deliver_io(vcpu, inti); |
481 | __u32 param0 = ((__u32)inti->io.subchannel_id << 16) | | ||
482 | inti->io.subchannel_nr; | ||
483 | __u64 param1 = ((__u64)inti->io.io_int_parm << 32) | | ||
484 | inti->io.io_int_word; | ||
485 | VCPU_EVENT(vcpu, 4, "interrupt: I/O %llx", inti->type); | ||
486 | vcpu->stat.deliver_io_int++; | ||
487 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, | ||
488 | param0, param1); | ||
489 | rc = put_guest_lc(vcpu, inti->io.subchannel_id, | ||
490 | (u16 *)__LC_SUBCHANNEL_ID); | ||
491 | rc |= put_guest_lc(vcpu, inti->io.subchannel_nr, | ||
492 | (u16 *)__LC_SUBCHANNEL_NR); | ||
493 | rc |= put_guest_lc(vcpu, inti->io.io_int_parm, | ||
494 | (u32 *)__LC_IO_INT_PARM); | ||
495 | rc |= put_guest_lc(vcpu, inti->io.io_int_word, | ||
496 | (u32 *)__LC_IO_INT_WORD); | ||
497 | rc |= write_guest_lc(vcpu, __LC_IO_OLD_PSW, | ||
498 | &vcpu->arch.sie_block->gpsw, | ||
499 | sizeof(psw_t)); | ||
500 | rc |= read_guest_lc(vcpu, __LC_IO_NEW_PSW, | ||
501 | &vcpu->arch.sie_block->gpsw, | ||
502 | sizeof(psw_t)); | ||
503 | break; | 733 | break; |
504 | } | ||
505 | default: | 734 | default: |
506 | BUG(); | 735 | BUG(); |
507 | } | 736 | } |
@@ -509,19 +738,6 @@ static int __must_check __do_deliver_interrupt(struct kvm_vcpu *vcpu, | |||
509 | return rc; | 738 | return rc; |
510 | } | 739 | } |
511 | 740 | ||
512 | static int __must_check deliver_ckc_interrupt(struct kvm_vcpu *vcpu) | ||
513 | { | ||
514 | int rc; | ||
515 | |||
516 | rc = put_guest_lc(vcpu, 0x1004, (u16 __user *)__LC_EXT_INT_CODE); | ||
517 | rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, | ||
518 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
519 | rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, | ||
520 | &vcpu->arch.sie_block->gpsw, | ||
521 | sizeof(psw_t)); | ||
522 | return rc; | ||
523 | } | ||
524 | |||
525 | /* Check whether SIGP interpretation facility has an external call pending */ | 741 | /* Check whether SIGP interpretation facility has an external call pending */ |
526 | int kvm_s390_si_ext_call_pending(struct kvm_vcpu *vcpu) | 742 | int kvm_s390_si_ext_call_pending(struct kvm_vcpu *vcpu) |
527 | { | 743 | { |
@@ -538,20 +754,11 @@ int kvm_s390_si_ext_call_pending(struct kvm_vcpu *vcpu) | |||
538 | 754 | ||
539 | int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu) | 755 | int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu) |
540 | { | 756 | { |
541 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
542 | struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int; | 757 | struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int; |
543 | struct kvm_s390_interrupt_info *inti; | 758 | struct kvm_s390_interrupt_info *inti; |
544 | int rc = 0; | 759 | int rc; |
545 | 760 | ||
546 | if (atomic_read(&li->active)) { | 761 | rc = !!deliverable_local_irqs(vcpu); |
547 | spin_lock(&li->lock); | ||
548 | list_for_each_entry(inti, &li->list, list) | ||
549 | if (__interrupt_is_deliverable(vcpu, inti)) { | ||
550 | rc = 1; | ||
551 | break; | ||
552 | } | ||
553 | spin_unlock(&li->lock); | ||
554 | } | ||
555 | 762 | ||
556 | if ((!rc) && atomic_read(&fi->active)) { | 763 | if ((!rc) && atomic_read(&fi->active)) { |
557 | spin_lock(&fi->lock); | 764 | spin_lock(&fi->lock); |
@@ -643,18 +850,15 @@ enum hrtimer_restart kvm_s390_idle_wakeup(struct hrtimer *timer) | |||
643 | void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu) | 850 | void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu) |
644 | { | 851 | { |
645 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | 852 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; |
646 | struct kvm_s390_interrupt_info *n, *inti = NULL; | ||
647 | 853 | ||
648 | spin_lock(&li->lock); | 854 | spin_lock(&li->lock); |
649 | list_for_each_entry_safe(inti, n, &li->list, list) { | 855 | li->pending_irqs = 0; |
650 | list_del(&inti->list); | 856 | bitmap_zero(li->sigp_emerg_pending, KVM_MAX_VCPUS); |
651 | kfree(inti); | 857 | memset(&li->irq, 0, sizeof(li->irq)); |
652 | } | ||
653 | atomic_set(&li->active, 0); | ||
654 | spin_unlock(&li->lock); | 858 | spin_unlock(&li->lock); |
655 | 859 | ||
656 | /* clear pending external calls set by sigp interpretation facility */ | 860 | /* clear pending external calls set by sigp interpretation facility */ |
657 | atomic_clear_mask(CPUSTAT_ECALL_PEND, &vcpu->arch.sie_block->cpuflags); | 861 | atomic_clear_mask(CPUSTAT_ECALL_PEND, li->cpuflags); |
658 | atomic_clear_mask(SIGP_CTRL_C, | 862 | atomic_clear_mask(SIGP_CTRL_C, |
659 | &vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].ctrl); | 863 | &vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].ctrl); |
660 | } | 864 | } |
@@ -664,34 +868,35 @@ int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu) | |||
664 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | 868 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; |
665 | struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int; | 869 | struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int; |
666 | struct kvm_s390_interrupt_info *n, *inti = NULL; | 870 | struct kvm_s390_interrupt_info *n, *inti = NULL; |
871 | deliver_irq_t func; | ||
667 | int deliver; | 872 | int deliver; |
668 | int rc = 0; | 873 | int rc = 0; |
874 | unsigned long irq_type; | ||
875 | unsigned long deliverable_irqs; | ||
669 | 876 | ||
670 | __reset_intercept_indicators(vcpu); | 877 | __reset_intercept_indicators(vcpu); |
671 | if (atomic_read(&li->active)) { | ||
672 | do { | ||
673 | deliver = 0; | ||
674 | spin_lock(&li->lock); | ||
675 | list_for_each_entry_safe(inti, n, &li->list, list) { | ||
676 | if (__interrupt_is_deliverable(vcpu, inti)) { | ||
677 | list_del(&inti->list); | ||
678 | deliver = 1; | ||
679 | break; | ||
680 | } | ||
681 | __set_intercept_indicator(vcpu, inti); | ||
682 | } | ||
683 | if (list_empty(&li->list)) | ||
684 | atomic_set(&li->active, 0); | ||
685 | spin_unlock(&li->lock); | ||
686 | if (deliver) { | ||
687 | rc = __do_deliver_interrupt(vcpu, inti); | ||
688 | kfree(inti); | ||
689 | } | ||
690 | } while (!rc && deliver); | ||
691 | } | ||
692 | 878 | ||
693 | if (!rc && kvm_cpu_has_pending_timer(vcpu)) | 879 | /* pending ckc conditions might have been invalidated */ |
694 | rc = deliver_ckc_interrupt(vcpu); | 880 | clear_bit(IRQ_PEND_EXT_CLOCK_COMP, &li->pending_irqs); |
881 | if (kvm_cpu_has_pending_timer(vcpu)) | ||
882 | set_bit(IRQ_PEND_EXT_CLOCK_COMP, &li->pending_irqs); | ||
883 | |||
884 | do { | ||
885 | deliverable_irqs = deliverable_local_irqs(vcpu); | ||
886 | /* bits are in the order of interrupt priority */ | ||
887 | irq_type = find_first_bit(&deliverable_irqs, IRQ_PEND_COUNT); | ||
888 | if (irq_type == IRQ_PEND_COUNT) | ||
889 | break; | ||
890 | func = deliver_irq_funcs[irq_type]; | ||
891 | if (!func) { | ||
892 | WARN_ON_ONCE(func == NULL); | ||
893 | clear_bit(irq_type, &li->pending_irqs); | ||
894 | continue; | ||
895 | } | ||
896 | rc = func(vcpu); | ||
897 | } while (!rc && irq_type != IRQ_PEND_COUNT); | ||
898 | |||
899 | set_intercept_indicators_local(vcpu); | ||
695 | 900 | ||
696 | if (!rc && atomic_read(&fi->active)) { | 901 | if (!rc && atomic_read(&fi->active)) { |
697 | do { | 902 | do { |
@@ -710,7 +915,7 @@ int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu) | |||
710 | atomic_set(&fi->active, 0); | 915 | atomic_set(&fi->active, 0); |
711 | spin_unlock(&fi->lock); | 916 | spin_unlock(&fi->lock); |
712 | if (deliver) { | 917 | if (deliver) { |
713 | rc = __do_deliver_interrupt(vcpu, inti); | 918 | rc = __deliver_floating_interrupt(vcpu, inti); |
714 | kfree(inti); | 919 | kfree(inti); |
715 | } | 920 | } |
716 | } while (!rc && deliver); | 921 | } while (!rc && deliver); |
@@ -719,23 +924,26 @@ int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu) | |||
719 | return rc; | 924 | return rc; |
720 | } | 925 | } |
721 | 926 | ||
722 | int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code) | 927 | static int __inject_prog(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) |
723 | { | 928 | { |
724 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | 929 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; |
725 | struct kvm_s390_interrupt_info *inti; | ||
726 | 930 | ||
727 | inti = kzalloc(sizeof(*inti), GFP_KERNEL); | 931 | li->irq.pgm = irq->u.pgm; |
728 | if (!inti) | 932 | set_bit(IRQ_PEND_PROG, &li->pending_irqs); |
729 | return -ENOMEM; | 933 | return 0; |
934 | } | ||
730 | 935 | ||
731 | inti->type = KVM_S390_PROGRAM_INT; | 936 | int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code) |
732 | inti->pgm.code = code; | 937 | { |
938 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
939 | struct kvm_s390_irq irq; | ||
733 | 940 | ||
734 | VCPU_EVENT(vcpu, 3, "inject: program check %d (from kernel)", code); | 941 | VCPU_EVENT(vcpu, 3, "inject: program check %d (from kernel)", code); |
735 | trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, inti->type, code, 0, 1); | 942 | trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_PROGRAM_INT, code, |
943 | 0, 1); | ||
736 | spin_lock(&li->lock); | 944 | spin_lock(&li->lock); |
737 | list_add(&inti->list, &li->list); | 945 | irq.u.pgm.code = code; |
738 | atomic_set(&li->active, 1); | 946 | __inject_prog(vcpu, &irq); |
739 | BUG_ON(waitqueue_active(li->wq)); | 947 | BUG_ON(waitqueue_active(li->wq)); |
740 | spin_unlock(&li->lock); | 948 | spin_unlock(&li->lock); |
741 | return 0; | 949 | return 0; |
@@ -745,27 +953,166 @@ int kvm_s390_inject_prog_irq(struct kvm_vcpu *vcpu, | |||
745 | struct kvm_s390_pgm_info *pgm_info) | 953 | struct kvm_s390_pgm_info *pgm_info) |
746 | { | 954 | { |
747 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | 955 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; |
748 | struct kvm_s390_interrupt_info *inti; | 956 | struct kvm_s390_irq irq; |
749 | 957 | int rc; | |
750 | inti = kzalloc(sizeof(*inti), GFP_KERNEL); | ||
751 | if (!inti) | ||
752 | return -ENOMEM; | ||
753 | 958 | ||
754 | VCPU_EVENT(vcpu, 3, "inject: prog irq %d (from kernel)", | 959 | VCPU_EVENT(vcpu, 3, "inject: prog irq %d (from kernel)", |
755 | pgm_info->code); | 960 | pgm_info->code); |
756 | trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_PROGRAM_INT, | 961 | trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_PROGRAM_INT, |
757 | pgm_info->code, 0, 1); | 962 | pgm_info->code, 0, 1); |
758 | |||
759 | inti->type = KVM_S390_PROGRAM_INT; | ||
760 | memcpy(&inti->pgm, pgm_info, sizeof(inti->pgm)); | ||
761 | spin_lock(&li->lock); | 963 | spin_lock(&li->lock); |
762 | list_add(&inti->list, &li->list); | 964 | irq.u.pgm = *pgm_info; |
763 | atomic_set(&li->active, 1); | 965 | rc = __inject_prog(vcpu, &irq); |
764 | BUG_ON(waitqueue_active(li->wq)); | 966 | BUG_ON(waitqueue_active(li->wq)); |
765 | spin_unlock(&li->lock); | 967 | spin_unlock(&li->lock); |
968 | return rc; | ||
969 | } | ||
970 | |||
971 | static int __inject_pfault_init(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) | ||
972 | { | ||
973 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
974 | |||
975 | VCPU_EVENT(vcpu, 3, "inject: external irq params:%x, params2:%llx", | ||
976 | irq->u.ext.ext_params, irq->u.ext.ext_params2); | ||
977 | trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_PFAULT_INIT, | ||
978 | irq->u.ext.ext_params, | ||
979 | irq->u.ext.ext_params2, 2); | ||
980 | |||
981 | li->irq.ext = irq->u.ext; | ||
982 | set_bit(IRQ_PEND_PFAULT_INIT, &li->pending_irqs); | ||
983 | atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags); | ||
766 | return 0; | 984 | return 0; |
767 | } | 985 | } |
768 | 986 | ||
987 | int __inject_extcall(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) | ||
988 | { | ||
989 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
990 | struct kvm_s390_extcall_info *extcall = &li->irq.extcall; | ||
991 | |||
992 | VCPU_EVENT(vcpu, 3, "inject: external call source-cpu:%u", | ||
993 | irq->u.extcall.code); | ||
994 | trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_EXTERNAL_CALL, | ||
995 | irq->u.extcall.code, 0, 2); | ||
996 | |||
997 | *extcall = irq->u.extcall; | ||
998 | set_bit(IRQ_PEND_EXT_EXTERNAL, &li->pending_irqs); | ||
999 | atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags); | ||
1000 | return 0; | ||
1001 | } | ||
1002 | |||
1003 | static int __inject_set_prefix(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) | ||
1004 | { | ||
1005 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
1006 | struct kvm_s390_prefix_info *prefix = &li->irq.prefix; | ||
1007 | |||
1008 | VCPU_EVENT(vcpu, 3, "inject: set prefix to %x (from user)", | ||
1009 | prefix->address); | ||
1010 | trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_SIGP_SET_PREFIX, | ||
1011 | prefix->address, 0, 2); | ||
1012 | |||
1013 | *prefix = irq->u.prefix; | ||
1014 | set_bit(IRQ_PEND_SET_PREFIX, &li->pending_irqs); | ||
1015 | return 0; | ||
1016 | } | ||
1017 | |||
1018 | static int __inject_sigp_stop(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) | ||
1019 | { | ||
1020 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
1021 | |||
1022 | trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_SIGP_STOP, 0, 0, 2); | ||
1023 | |||
1024 | li->action_bits |= ACTION_STOP_ON_STOP; | ||
1025 | set_bit(IRQ_PEND_SIGP_STOP, &li->pending_irqs); | ||
1026 | return 0; | ||
1027 | } | ||
1028 | |||
1029 | static int __inject_sigp_restart(struct kvm_vcpu *vcpu, | ||
1030 | struct kvm_s390_irq *irq) | ||
1031 | { | ||
1032 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
1033 | |||
1034 | VCPU_EVENT(vcpu, 3, "inject: restart type %llx", irq->type); | ||
1035 | trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_RESTART, 0, 0, 2); | ||
1036 | |||
1037 | set_bit(IRQ_PEND_RESTART, &li->pending_irqs); | ||
1038 | return 0; | ||
1039 | } | ||
1040 | |||
1041 | static int __inject_sigp_emergency(struct kvm_vcpu *vcpu, | ||
1042 | struct kvm_s390_irq *irq) | ||
1043 | { | ||
1044 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
1045 | struct kvm_s390_emerg_info *emerg = &li->irq.emerg; | ||
1046 | |||
1047 | VCPU_EVENT(vcpu, 3, "inject: emergency %u\n", | ||
1048 | irq->u.emerg.code); | ||
1049 | trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_EMERGENCY, | ||
1050 | emerg->code, 0, 2); | ||
1051 | |||
1052 | set_bit(emerg->code, li->sigp_emerg_pending); | ||
1053 | set_bit(IRQ_PEND_EXT_EMERGENCY, &li->pending_irqs); | ||
1054 | atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags); | ||
1055 | return 0; | ||
1056 | } | ||
1057 | |||
1058 | static int __inject_mchk(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) | ||
1059 | { | ||
1060 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
1061 | struct kvm_s390_mchk_info *mchk = &li->irq.mchk; | ||
1062 | |||
1063 | VCPU_EVENT(vcpu, 5, "inject: machine check parm64:%llx", | ||
1064 | mchk->mcic); | ||
1065 | trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_MCHK, 0, | ||
1066 | mchk->mcic, 2); | ||
1067 | |||
1068 | /* | ||
1069 | * Because repressible machine checks can be indicated along with | ||
1070 | * exigent machine checks (PoP, Chapter 11, Interruption action) | ||
1071 | * we need to combine cr14, mcic and external damage code. | ||
1072 | * Failing storage address and the logout area should not be or'ed | ||
1073 | * together, we just indicate the last occurrence of the corresponding | ||
1074 | * machine check | ||
1075 | */ | ||
1076 | mchk->cr14 |= irq->u.mchk.cr14; | ||
1077 | mchk->mcic |= irq->u.mchk.mcic; | ||
1078 | mchk->ext_damage_code |= irq->u.mchk.ext_damage_code; | ||
1079 | mchk->failing_storage_address = irq->u.mchk.failing_storage_address; | ||
1080 | memcpy(&mchk->fixed_logout, &irq->u.mchk.fixed_logout, | ||
1081 | sizeof(mchk->fixed_logout)); | ||
1082 | if (mchk->mcic & MCHK_EX_MASK) | ||
1083 | set_bit(IRQ_PEND_MCHK_EX, &li->pending_irqs); | ||
1084 | else if (mchk->mcic & MCHK_REP_MASK) | ||
1085 | set_bit(IRQ_PEND_MCHK_REP, &li->pending_irqs); | ||
1086 | return 0; | ||
1087 | } | ||
1088 | |||
1089 | static int __inject_ckc(struct kvm_vcpu *vcpu) | ||
1090 | { | ||
1091 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
1092 | |||
1093 | VCPU_EVENT(vcpu, 3, "inject: type %x", KVM_S390_INT_CLOCK_COMP); | ||
1094 | trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_CLOCK_COMP, | ||
1095 | 0, 0, 2); | ||
1096 | |||
1097 | set_bit(IRQ_PEND_EXT_CLOCK_COMP, &li->pending_irqs); | ||
1098 | atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags); | ||
1099 | return 0; | ||
1100 | } | ||
1101 | |||
1102 | static int __inject_cpu_timer(struct kvm_vcpu *vcpu) | ||
1103 | { | ||
1104 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
1105 | |||
1106 | VCPU_EVENT(vcpu, 3, "inject: type %x", KVM_S390_INT_CPU_TIMER); | ||
1107 | trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_CPU_TIMER, | ||
1108 | 0, 0, 2); | ||
1109 | |||
1110 | set_bit(IRQ_PEND_EXT_CPU_TIMER, &li->pending_irqs); | ||
1111 | atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags); | ||
1112 | return 0; | ||
1113 | } | ||
1114 | |||
1115 | |||
769 | struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, | 1116 | struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, |
770 | u64 cr6, u64 schid) | 1117 | u64 cr6, u64 schid) |
771 | { | 1118 | { |
@@ -851,7 +1198,17 @@ static int __inject_vm(struct kvm *kvm, struct kvm_s390_interrupt_info *inti) | |||
851 | dst_vcpu = kvm_get_vcpu(kvm, sigcpu); | 1198 | dst_vcpu = kvm_get_vcpu(kvm, sigcpu); |
852 | li = &dst_vcpu->arch.local_int; | 1199 | li = &dst_vcpu->arch.local_int; |
853 | spin_lock(&li->lock); | 1200 | spin_lock(&li->lock); |
854 | atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags); | 1201 | switch (inti->type) { |
1202 | case KVM_S390_MCHK: | ||
1203 | atomic_set_mask(CPUSTAT_STOP_INT, li->cpuflags); | ||
1204 | break; | ||
1205 | case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: | ||
1206 | atomic_set_mask(CPUSTAT_IO_INT, li->cpuflags); | ||
1207 | break; | ||
1208 | default: | ||
1209 | atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags); | ||
1210 | break; | ||
1211 | } | ||
855 | spin_unlock(&li->lock); | 1212 | spin_unlock(&li->lock); |
856 | kvm_s390_vcpu_wakeup(kvm_get_vcpu(kvm, sigcpu)); | 1213 | kvm_s390_vcpu_wakeup(kvm_get_vcpu(kvm, sigcpu)); |
857 | unlock_fi: | 1214 | unlock_fi: |
@@ -920,92 +1277,85 @@ void kvm_s390_reinject_io_int(struct kvm *kvm, | |||
920 | __inject_vm(kvm, inti); | 1277 | __inject_vm(kvm, inti); |
921 | } | 1278 | } |
922 | 1279 | ||
923 | int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, | 1280 | int s390int_to_s390irq(struct kvm_s390_interrupt *s390int, |
924 | struct kvm_s390_interrupt *s390int) | 1281 | struct kvm_s390_irq *irq) |
925 | { | 1282 | { |
926 | struct kvm_s390_local_interrupt *li; | 1283 | irq->type = s390int->type; |
927 | struct kvm_s390_interrupt_info *inti; | 1284 | switch (irq->type) { |
1285 | case KVM_S390_PROGRAM_INT: | ||
1286 | if (s390int->parm & 0xffff0000) | ||
1287 | return -EINVAL; | ||
1288 | irq->u.pgm.code = s390int->parm; | ||
1289 | break; | ||
1290 | case KVM_S390_SIGP_SET_PREFIX: | ||
1291 | irq->u.prefix.address = s390int->parm; | ||
1292 | break; | ||
1293 | case KVM_S390_INT_EXTERNAL_CALL: | ||
1294 | if (irq->u.extcall.code & 0xffff0000) | ||
1295 | return -EINVAL; | ||
1296 | irq->u.extcall.code = s390int->parm; | ||
1297 | break; | ||
1298 | case KVM_S390_INT_EMERGENCY: | ||
1299 | if (irq->u.emerg.code & 0xffff0000) | ||
1300 | return -EINVAL; | ||
1301 | irq->u.emerg.code = s390int->parm; | ||
1302 | break; | ||
1303 | case KVM_S390_MCHK: | ||
1304 | irq->u.mchk.mcic = s390int->parm64; | ||
1305 | break; | ||
1306 | } | ||
1307 | return 0; | ||
1308 | } | ||
928 | 1309 | ||
929 | inti = kzalloc(sizeof(*inti), GFP_KERNEL); | 1310 | int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) |
930 | if (!inti) | 1311 | { |
931 | return -ENOMEM; | 1312 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; |
1313 | int rc; | ||
932 | 1314 | ||
933 | switch (s390int->type) { | 1315 | spin_lock(&li->lock); |
1316 | switch (irq->type) { | ||
934 | case KVM_S390_PROGRAM_INT: | 1317 | case KVM_S390_PROGRAM_INT: |
935 | if (s390int->parm & 0xffff0000) { | ||
936 | kfree(inti); | ||
937 | return -EINVAL; | ||
938 | } | ||
939 | inti->type = s390int->type; | ||
940 | inti->pgm.code = s390int->parm; | ||
941 | VCPU_EVENT(vcpu, 3, "inject: program check %d (from user)", | 1318 | VCPU_EVENT(vcpu, 3, "inject: program check %d (from user)", |
942 | s390int->parm); | 1319 | irq->u.pgm.code); |
1320 | rc = __inject_prog(vcpu, irq); | ||
943 | break; | 1321 | break; |
944 | case KVM_S390_SIGP_SET_PREFIX: | 1322 | case KVM_S390_SIGP_SET_PREFIX: |
945 | inti->prefix.address = s390int->parm; | 1323 | rc = __inject_set_prefix(vcpu, irq); |
946 | inti->type = s390int->type; | ||
947 | VCPU_EVENT(vcpu, 3, "inject: set prefix to %x (from user)", | ||
948 | s390int->parm); | ||
949 | break; | 1324 | break; |
950 | case KVM_S390_SIGP_STOP: | 1325 | case KVM_S390_SIGP_STOP: |
1326 | rc = __inject_sigp_stop(vcpu, irq); | ||
1327 | break; | ||
951 | case KVM_S390_RESTART: | 1328 | case KVM_S390_RESTART: |
1329 | rc = __inject_sigp_restart(vcpu, irq); | ||
1330 | break; | ||
952 | case KVM_S390_INT_CLOCK_COMP: | 1331 | case KVM_S390_INT_CLOCK_COMP: |
1332 | rc = __inject_ckc(vcpu); | ||
1333 | break; | ||
953 | case KVM_S390_INT_CPU_TIMER: | 1334 | case KVM_S390_INT_CPU_TIMER: |
954 | VCPU_EVENT(vcpu, 3, "inject: type %x", s390int->type); | 1335 | rc = __inject_cpu_timer(vcpu); |
955 | inti->type = s390int->type; | ||
956 | break; | 1336 | break; |
957 | case KVM_S390_INT_EXTERNAL_CALL: | 1337 | case KVM_S390_INT_EXTERNAL_CALL: |
958 | if (s390int->parm & 0xffff0000) { | 1338 | rc = __inject_extcall(vcpu, irq); |
959 | kfree(inti); | ||
960 | return -EINVAL; | ||
961 | } | ||
962 | VCPU_EVENT(vcpu, 3, "inject: external call source-cpu:%u", | ||
963 | s390int->parm); | ||
964 | inti->type = s390int->type; | ||
965 | inti->extcall.code = s390int->parm; | ||
966 | break; | 1339 | break; |
967 | case KVM_S390_INT_EMERGENCY: | 1340 | case KVM_S390_INT_EMERGENCY: |
968 | if (s390int->parm & 0xffff0000) { | 1341 | rc = __inject_sigp_emergency(vcpu, irq); |
969 | kfree(inti); | ||
970 | return -EINVAL; | ||
971 | } | ||
972 | VCPU_EVENT(vcpu, 3, "inject: emergency %u\n", s390int->parm); | ||
973 | inti->type = s390int->type; | ||
974 | inti->emerg.code = s390int->parm; | ||
975 | break; | 1342 | break; |
976 | case KVM_S390_MCHK: | 1343 | case KVM_S390_MCHK: |
977 | VCPU_EVENT(vcpu, 5, "inject: machine check parm64:%llx", | 1344 | rc = __inject_mchk(vcpu, irq); |
978 | s390int->parm64); | ||
979 | inti->type = s390int->type; | ||
980 | inti->mchk.mcic = s390int->parm64; | ||
981 | break; | 1345 | break; |
982 | case KVM_S390_INT_PFAULT_INIT: | 1346 | case KVM_S390_INT_PFAULT_INIT: |
983 | inti->type = s390int->type; | 1347 | rc = __inject_pfault_init(vcpu, irq); |
984 | inti->ext.ext_params2 = s390int->parm64; | ||
985 | break; | 1348 | break; |
986 | case KVM_S390_INT_VIRTIO: | 1349 | case KVM_S390_INT_VIRTIO: |
987 | case KVM_S390_INT_SERVICE: | 1350 | case KVM_S390_INT_SERVICE: |
988 | case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: | 1351 | case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: |
989 | default: | 1352 | default: |
990 | kfree(inti); | 1353 | rc = -EINVAL; |
991 | return -EINVAL; | ||
992 | } | 1354 | } |
993 | trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, s390int->type, s390int->parm, | ||
994 | s390int->parm64, 2); | ||
995 | |||
996 | li = &vcpu->arch.local_int; | ||
997 | spin_lock(&li->lock); | ||
998 | if (inti->type == KVM_S390_PROGRAM_INT) | ||
999 | list_add(&inti->list, &li->list); | ||
1000 | else | ||
1001 | list_add_tail(&inti->list, &li->list); | ||
1002 | atomic_set(&li->active, 1); | ||
1003 | if (inti->type == KVM_S390_SIGP_STOP) | ||
1004 | li->action_bits |= ACTION_STOP_ON_STOP; | ||
1005 | atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags); | ||
1006 | spin_unlock(&li->lock); | 1355 | spin_unlock(&li->lock); |
1007 | kvm_s390_vcpu_wakeup(vcpu); | 1356 | if (!rc) |
1008 | return 0; | 1357 | kvm_s390_vcpu_wakeup(vcpu); |
1358 | return rc; | ||
1009 | } | 1359 | } |
1010 | 1360 | ||
1011 | void kvm_s390_clear_float_irqs(struct kvm *kvm) | 1361 | void kvm_s390_clear_float_irqs(struct kvm *kvm) |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 6b049ee75a56..3e09801e3104 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -81,10 +81,17 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { | |||
81 | { "instruction_sigp_sense_running", VCPU_STAT(instruction_sigp_sense_running) }, | 81 | { "instruction_sigp_sense_running", VCPU_STAT(instruction_sigp_sense_running) }, |
82 | { "instruction_sigp_external_call", VCPU_STAT(instruction_sigp_external_call) }, | 82 | { "instruction_sigp_external_call", VCPU_STAT(instruction_sigp_external_call) }, |
83 | { "instruction_sigp_emergency", VCPU_STAT(instruction_sigp_emergency) }, | 83 | { "instruction_sigp_emergency", VCPU_STAT(instruction_sigp_emergency) }, |
84 | { "instruction_sigp_cond_emergency", VCPU_STAT(instruction_sigp_cond_emergency) }, | ||
85 | { "instruction_sigp_start", VCPU_STAT(instruction_sigp_start) }, | ||
84 | { "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) }, | 86 | { "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) }, |
87 | { "instruction_sigp_stop_store_status", VCPU_STAT(instruction_sigp_stop_store_status) }, | ||
88 | { "instruction_sigp_store_status", VCPU_STAT(instruction_sigp_store_status) }, | ||
85 | { "instruction_sigp_set_arch", VCPU_STAT(instruction_sigp_arch) }, | 89 | { "instruction_sigp_set_arch", VCPU_STAT(instruction_sigp_arch) }, |
86 | { "instruction_sigp_set_prefix", VCPU_STAT(instruction_sigp_prefix) }, | 90 | { "instruction_sigp_set_prefix", VCPU_STAT(instruction_sigp_prefix) }, |
87 | { "instruction_sigp_restart", VCPU_STAT(instruction_sigp_restart) }, | 91 | { "instruction_sigp_restart", VCPU_STAT(instruction_sigp_restart) }, |
92 | { "instruction_sigp_cpu_reset", VCPU_STAT(instruction_sigp_cpu_reset) }, | ||
93 | { "instruction_sigp_init_cpu_reset", VCPU_STAT(instruction_sigp_init_cpu_reset) }, | ||
94 | { "instruction_sigp_unknown", VCPU_STAT(instruction_sigp_unknown) }, | ||
88 | { "diagnose_10", VCPU_STAT(diagnose_10) }, | 95 | { "diagnose_10", VCPU_STAT(diagnose_10) }, |
89 | { "diagnose_44", VCPU_STAT(diagnose_44) }, | 96 | { "diagnose_44", VCPU_STAT(diagnose_44) }, |
90 | { "diagnose_9c", VCPU_STAT(diagnose_9c) }, | 97 | { "diagnose_9c", VCPU_STAT(diagnose_9c) }, |
@@ -453,6 +460,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | |||
453 | spin_lock_init(&kvm->arch.float_int.lock); | 460 | spin_lock_init(&kvm->arch.float_int.lock); |
454 | INIT_LIST_HEAD(&kvm->arch.float_int.list); | 461 | INIT_LIST_HEAD(&kvm->arch.float_int.list); |
455 | init_waitqueue_head(&kvm->arch.ipte_wq); | 462 | init_waitqueue_head(&kvm->arch.ipte_wq); |
463 | mutex_init(&kvm->arch.ipte_mutex); | ||
456 | 464 | ||
457 | debug_register_view(kvm->arch.dbf, &debug_sprintf_view); | 465 | debug_register_view(kvm->arch.dbf, &debug_sprintf_view); |
458 | VM_EVENT(kvm, 3, "%s", "vm created"); | 466 | VM_EVENT(kvm, 3, "%s", "vm created"); |
@@ -711,7 +719,6 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, | |||
711 | } | 719 | } |
712 | 720 | ||
713 | spin_lock_init(&vcpu->arch.local_int.lock); | 721 | spin_lock_init(&vcpu->arch.local_int.lock); |
714 | INIT_LIST_HEAD(&vcpu->arch.local_int.list); | ||
715 | vcpu->arch.local_int.float_int = &kvm->arch.float_int; | 722 | vcpu->arch.local_int.float_int = &kvm->arch.float_int; |
716 | vcpu->arch.local_int.wq = &vcpu->wq; | 723 | vcpu->arch.local_int.wq = &vcpu->wq; |
717 | vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags; | 724 | vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags; |
@@ -1114,13 +1121,15 @@ static void __kvm_inject_pfault_token(struct kvm_vcpu *vcpu, bool start_token, | |||
1114 | unsigned long token) | 1121 | unsigned long token) |
1115 | { | 1122 | { |
1116 | struct kvm_s390_interrupt inti; | 1123 | struct kvm_s390_interrupt inti; |
1117 | inti.parm64 = token; | 1124 | struct kvm_s390_irq irq; |
1118 | 1125 | ||
1119 | if (start_token) { | 1126 | if (start_token) { |
1120 | inti.type = KVM_S390_INT_PFAULT_INIT; | 1127 | irq.u.ext.ext_params2 = token; |
1121 | WARN_ON_ONCE(kvm_s390_inject_vcpu(vcpu, &inti)); | 1128 | irq.type = KVM_S390_INT_PFAULT_INIT; |
1129 | WARN_ON_ONCE(kvm_s390_inject_vcpu(vcpu, &irq)); | ||
1122 | } else { | 1130 | } else { |
1123 | inti.type = KVM_S390_INT_PFAULT_DONE; | 1131 | inti.type = KVM_S390_INT_PFAULT_DONE; |
1132 | inti.parm64 = token; | ||
1124 | WARN_ON_ONCE(kvm_s390_inject_vm(vcpu->kvm, &inti)); | 1133 | WARN_ON_ONCE(kvm_s390_inject_vm(vcpu->kvm, &inti)); |
1125 | } | 1134 | } |
1126 | } | 1135 | } |
@@ -1614,11 +1623,14 @@ long kvm_arch_vcpu_ioctl(struct file *filp, | |||
1614 | switch (ioctl) { | 1623 | switch (ioctl) { |
1615 | case KVM_S390_INTERRUPT: { | 1624 | case KVM_S390_INTERRUPT: { |
1616 | struct kvm_s390_interrupt s390int; | 1625 | struct kvm_s390_interrupt s390int; |
1626 | struct kvm_s390_irq s390irq; | ||
1617 | 1627 | ||
1618 | r = -EFAULT; | 1628 | r = -EFAULT; |
1619 | if (copy_from_user(&s390int, argp, sizeof(s390int))) | 1629 | if (copy_from_user(&s390int, argp, sizeof(s390int))) |
1620 | break; | 1630 | break; |
1621 | r = kvm_s390_inject_vcpu(vcpu, &s390int); | 1631 | if (s390int_to_s390irq(&s390int, &s390irq)) |
1632 | return -EINVAL; | ||
1633 | r = kvm_s390_inject_vcpu(vcpu, &s390irq); | ||
1622 | break; | 1634 | break; |
1623 | } | 1635 | } |
1624 | case KVM_S390_STORE_STATUS: | 1636 | case KVM_S390_STORE_STATUS: |
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index 244d02303182..a8f3d9b71c11 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h | |||
@@ -24,8 +24,6 @@ typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu); | |||
24 | /* declare vfacilities extern */ | 24 | /* declare vfacilities extern */ |
25 | extern unsigned long *vfacilities; | 25 | extern unsigned long *vfacilities; |
26 | 26 | ||
27 | int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu); | ||
28 | |||
29 | /* Transactional Memory Execution related macros */ | 27 | /* Transactional Memory Execution related macros */ |
30 | #define IS_TE_ENABLED(vcpu) ((vcpu->arch.sie_block->ecb & 0x10)) | 28 | #define IS_TE_ENABLED(vcpu) ((vcpu->arch.sie_block->ecb & 0x10)) |
31 | #define TDB_FORMAT1 1 | 29 | #define TDB_FORMAT1 1 |
@@ -144,7 +142,7 @@ void kvm_s390_clear_float_irqs(struct kvm *kvm); | |||
144 | int __must_check kvm_s390_inject_vm(struct kvm *kvm, | 142 | int __must_check kvm_s390_inject_vm(struct kvm *kvm, |
145 | struct kvm_s390_interrupt *s390int); | 143 | struct kvm_s390_interrupt *s390int); |
146 | int __must_check kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, | 144 | int __must_check kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, |
147 | struct kvm_s390_interrupt *s390int); | 145 | struct kvm_s390_irq *irq); |
148 | int __must_check kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code); | 146 | int __must_check kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code); |
149 | struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, | 147 | struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, |
150 | u64 cr6, u64 schid); | 148 | u64 cr6, u64 schid); |
@@ -152,6 +150,10 @@ void kvm_s390_reinject_io_int(struct kvm *kvm, | |||
152 | struct kvm_s390_interrupt_info *inti); | 150 | struct kvm_s390_interrupt_info *inti); |
153 | int kvm_s390_mask_adapter(struct kvm *kvm, unsigned int id, bool masked); | 151 | int kvm_s390_mask_adapter(struct kvm *kvm, unsigned int id, bool masked); |
154 | 152 | ||
153 | /* implemented in intercept.c */ | ||
154 | void kvm_s390_rewind_psw(struct kvm_vcpu *vcpu, int ilc); | ||
155 | int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu); | ||
156 | |||
155 | /* implemented in priv.c */ | 157 | /* implemented in priv.c */ |
156 | int is_valid_psw(psw_t *psw); | 158 | int is_valid_psw(psw_t *psw); |
157 | int kvm_s390_handle_b2(struct kvm_vcpu *vcpu); | 159 | int kvm_s390_handle_b2(struct kvm_vcpu *vcpu); |
@@ -222,6 +224,9 @@ static inline int kvm_s390_inject_prog_cond(struct kvm_vcpu *vcpu, int rc) | |||
222 | return kvm_s390_inject_prog_irq(vcpu, &vcpu->arch.pgm); | 224 | return kvm_s390_inject_prog_irq(vcpu, &vcpu->arch.pgm); |
223 | } | 225 | } |
224 | 226 | ||
227 | int s390int_to_s390irq(struct kvm_s390_interrupt *s390int, | ||
228 | struct kvm_s390_irq *s390irq); | ||
229 | |||
225 | /* implemented in interrupt.c */ | 230 | /* implemented in interrupt.c */ |
226 | int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu); | 231 | int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu); |
227 | int psw_extint_disabled(struct kvm_vcpu *vcpu); | 232 | int psw_extint_disabled(struct kvm_vcpu *vcpu); |
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index f47cb0c6d906..1be578d64dfc 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c | |||
@@ -180,21 +180,18 @@ static int handle_skey(struct kvm_vcpu *vcpu) | |||
180 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | 180 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) |
181 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | 181 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); |
182 | 182 | ||
183 | vcpu->arch.sie_block->gpsw.addr = | 183 | kvm_s390_rewind_psw(vcpu, 4); |
184 | __rewind_psw(vcpu->arch.sie_block->gpsw, 4); | ||
185 | VCPU_EVENT(vcpu, 4, "%s", "retrying storage key operation"); | 184 | VCPU_EVENT(vcpu, 4, "%s", "retrying storage key operation"); |
186 | return 0; | 185 | return 0; |
187 | } | 186 | } |
188 | 187 | ||
189 | static int handle_ipte_interlock(struct kvm_vcpu *vcpu) | 188 | static int handle_ipte_interlock(struct kvm_vcpu *vcpu) |
190 | { | 189 | { |
191 | psw_t *psw = &vcpu->arch.sie_block->gpsw; | ||
192 | |||
193 | vcpu->stat.instruction_ipte_interlock++; | 190 | vcpu->stat.instruction_ipte_interlock++; |
194 | if (psw_bits(*psw).p) | 191 | if (psw_bits(vcpu->arch.sie_block->gpsw).p) |
195 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | 192 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); |
196 | wait_event(vcpu->kvm->arch.ipte_wq, !ipte_lock_held(vcpu)); | 193 | wait_event(vcpu->kvm->arch.ipte_wq, !ipte_lock_held(vcpu)); |
197 | psw->addr = __rewind_psw(*psw, 4); | 194 | kvm_s390_rewind_psw(vcpu, 4); |
198 | VCPU_EVENT(vcpu, 4, "%s", "retrying ipte interlock operation"); | 195 | VCPU_EVENT(vcpu, 4, "%s", "retrying ipte interlock operation"); |
199 | return 0; | 196 | return 0; |
200 | } | 197 | } |
@@ -650,10 +647,7 @@ static int handle_pfmf(struct kvm_vcpu *vcpu) | |||
650 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 647 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
651 | 648 | ||
652 | start = vcpu->run->s.regs.gprs[reg2] & PAGE_MASK; | 649 | start = vcpu->run->s.regs.gprs[reg2] & PAGE_MASK; |
653 | if (vcpu->run->s.regs.gprs[reg1] & PFMF_CF) { | 650 | start = kvm_s390_logical_to_effective(vcpu, start); |
654 | if (kvm_s390_check_low_addr_protection(vcpu, start)) | ||
655 | return kvm_s390_inject_prog_irq(vcpu, &vcpu->arch.pgm); | ||
656 | } | ||
657 | 651 | ||
658 | switch (vcpu->run->s.regs.gprs[reg1] & PFMF_FSC) { | 652 | switch (vcpu->run->s.regs.gprs[reg1] & PFMF_FSC) { |
659 | case 0x00000000: | 653 | case 0x00000000: |
@@ -669,6 +663,12 @@ static int handle_pfmf(struct kvm_vcpu *vcpu) | |||
669 | default: | 663 | default: |
670 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 664 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
671 | } | 665 | } |
666 | |||
667 | if (vcpu->run->s.regs.gprs[reg1] & PFMF_CF) { | ||
668 | if (kvm_s390_check_low_addr_protection(vcpu, start)) | ||
669 | return kvm_s390_inject_prog_irq(vcpu, &vcpu->arch.pgm); | ||
670 | } | ||
671 | |||
672 | while (start < end) { | 672 | while (start < end) { |
673 | unsigned long useraddr, abs_addr; | 673 | unsigned long useraddr, abs_addr; |
674 | 674 | ||
@@ -725,8 +725,7 @@ static int handle_essa(struct kvm_vcpu *vcpu) | |||
725 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 725 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
726 | 726 | ||
727 | /* Rewind PSW to repeat the ESSA instruction */ | 727 | /* Rewind PSW to repeat the ESSA instruction */ |
728 | vcpu->arch.sie_block->gpsw.addr = | 728 | kvm_s390_rewind_psw(vcpu, 4); |
729 | __rewind_psw(vcpu->arch.sie_block->gpsw, 4); | ||
730 | vcpu->arch.sie_block->cbrlo &= PAGE_MASK; /* reset nceo */ | 729 | vcpu->arch.sie_block->cbrlo &= PAGE_MASK; /* reset nceo */ |
731 | cbrlo = phys_to_virt(vcpu->arch.sie_block->cbrlo); | 730 | cbrlo = phys_to_virt(vcpu->arch.sie_block->cbrlo); |
732 | down_read(&gmap->mm->mmap_sem); | 731 | down_read(&gmap->mm->mmap_sem); |
@@ -769,8 +768,8 @@ int kvm_s390_handle_lctl(struct kvm_vcpu *vcpu) | |||
769 | { | 768 | { |
770 | int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; | 769 | int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; |
771 | int reg3 = vcpu->arch.sie_block->ipa & 0x000f; | 770 | int reg3 = vcpu->arch.sie_block->ipa & 0x000f; |
772 | u32 val = 0; | 771 | int reg, rc, nr_regs; |
773 | int reg, rc; | 772 | u32 ctl_array[16]; |
774 | u64 ga; | 773 | u64 ga; |
775 | 774 | ||
776 | vcpu->stat.instruction_lctl++; | 775 | vcpu->stat.instruction_lctl++; |
@@ -786,19 +785,20 @@ int kvm_s390_handle_lctl(struct kvm_vcpu *vcpu) | |||
786 | VCPU_EVENT(vcpu, 5, "lctl r1:%x, r3:%x, addr:%llx", reg1, reg3, ga); | 785 | VCPU_EVENT(vcpu, 5, "lctl r1:%x, r3:%x, addr:%llx", reg1, reg3, ga); |
787 | trace_kvm_s390_handle_lctl(vcpu, 0, reg1, reg3, ga); | 786 | trace_kvm_s390_handle_lctl(vcpu, 0, reg1, reg3, ga); |
788 | 787 | ||
788 | nr_regs = ((reg3 - reg1) & 0xf) + 1; | ||
789 | rc = read_guest(vcpu, ga, ctl_array, nr_regs * sizeof(u32)); | ||
790 | if (rc) | ||
791 | return kvm_s390_inject_prog_cond(vcpu, rc); | ||
789 | reg = reg1; | 792 | reg = reg1; |
793 | nr_regs = 0; | ||
790 | do { | 794 | do { |
791 | rc = read_guest(vcpu, ga, &val, sizeof(val)); | ||
792 | if (rc) | ||
793 | return kvm_s390_inject_prog_cond(vcpu, rc); | ||
794 | vcpu->arch.sie_block->gcr[reg] &= 0xffffffff00000000ul; | 795 | vcpu->arch.sie_block->gcr[reg] &= 0xffffffff00000000ul; |
795 | vcpu->arch.sie_block->gcr[reg] |= val; | 796 | vcpu->arch.sie_block->gcr[reg] |= ctl_array[nr_regs++]; |
796 | ga += 4; | ||
797 | if (reg == reg3) | 797 | if (reg == reg3) |
798 | break; | 798 | break; |
799 | reg = (reg + 1) % 16; | 799 | reg = (reg + 1) % 16; |
800 | } while (1); | 800 | } while (1); |
801 | 801 | kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu); | |
802 | return 0; | 802 | return 0; |
803 | } | 803 | } |
804 | 804 | ||
@@ -806,9 +806,9 @@ int kvm_s390_handle_stctl(struct kvm_vcpu *vcpu) | |||
806 | { | 806 | { |
807 | int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; | 807 | int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; |
808 | int reg3 = vcpu->arch.sie_block->ipa & 0x000f; | 808 | int reg3 = vcpu->arch.sie_block->ipa & 0x000f; |
809 | int reg, rc, nr_regs; | ||
810 | u32 ctl_array[16]; | ||
809 | u64 ga; | 811 | u64 ga; |
810 | u32 val; | ||
811 | int reg, rc; | ||
812 | 812 | ||
813 | vcpu->stat.instruction_stctl++; | 813 | vcpu->stat.instruction_stctl++; |
814 | 814 | ||
@@ -824,26 +824,24 @@ int kvm_s390_handle_stctl(struct kvm_vcpu *vcpu) | |||
824 | trace_kvm_s390_handle_stctl(vcpu, 0, reg1, reg3, ga); | 824 | trace_kvm_s390_handle_stctl(vcpu, 0, reg1, reg3, ga); |
825 | 825 | ||
826 | reg = reg1; | 826 | reg = reg1; |
827 | nr_regs = 0; | ||
827 | do { | 828 | do { |
828 | val = vcpu->arch.sie_block->gcr[reg] & 0x00000000fffffffful; | 829 | ctl_array[nr_regs++] = vcpu->arch.sie_block->gcr[reg]; |
829 | rc = write_guest(vcpu, ga, &val, sizeof(val)); | ||
830 | if (rc) | ||
831 | return kvm_s390_inject_prog_cond(vcpu, rc); | ||
832 | ga += 4; | ||
833 | if (reg == reg3) | 830 | if (reg == reg3) |
834 | break; | 831 | break; |
835 | reg = (reg + 1) % 16; | 832 | reg = (reg + 1) % 16; |
836 | } while (1); | 833 | } while (1); |
837 | 834 | rc = write_guest(vcpu, ga, ctl_array, nr_regs * sizeof(u32)); | |
838 | return 0; | 835 | return rc ? kvm_s390_inject_prog_cond(vcpu, rc) : 0; |
839 | } | 836 | } |
840 | 837 | ||
841 | static int handle_lctlg(struct kvm_vcpu *vcpu) | 838 | static int handle_lctlg(struct kvm_vcpu *vcpu) |
842 | { | 839 | { |
843 | int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; | 840 | int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; |
844 | int reg3 = vcpu->arch.sie_block->ipa & 0x000f; | 841 | int reg3 = vcpu->arch.sie_block->ipa & 0x000f; |
845 | u64 ga, val; | 842 | int reg, rc, nr_regs; |
846 | int reg, rc; | 843 | u64 ctl_array[16]; |
844 | u64 ga; | ||
847 | 845 | ||
848 | vcpu->stat.instruction_lctlg++; | 846 | vcpu->stat.instruction_lctlg++; |
849 | 847 | ||
@@ -855,22 +853,22 @@ static int handle_lctlg(struct kvm_vcpu *vcpu) | |||
855 | if (ga & 7) | 853 | if (ga & 7) |
856 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 854 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
857 | 855 | ||
858 | reg = reg1; | ||
859 | |||
860 | VCPU_EVENT(vcpu, 5, "lctlg r1:%x, r3:%x, addr:%llx", reg1, reg3, ga); | 856 | VCPU_EVENT(vcpu, 5, "lctlg r1:%x, r3:%x, addr:%llx", reg1, reg3, ga); |
861 | trace_kvm_s390_handle_lctl(vcpu, 1, reg1, reg3, ga); | 857 | trace_kvm_s390_handle_lctl(vcpu, 1, reg1, reg3, ga); |
862 | 858 | ||
859 | nr_regs = ((reg3 - reg1) & 0xf) + 1; | ||
860 | rc = read_guest(vcpu, ga, ctl_array, nr_regs * sizeof(u64)); | ||
861 | if (rc) | ||
862 | return kvm_s390_inject_prog_cond(vcpu, rc); | ||
863 | reg = reg1; | ||
864 | nr_regs = 0; | ||
863 | do { | 865 | do { |
864 | rc = read_guest(vcpu, ga, &val, sizeof(val)); | 866 | vcpu->arch.sie_block->gcr[reg] = ctl_array[nr_regs++]; |
865 | if (rc) | ||
866 | return kvm_s390_inject_prog_cond(vcpu, rc); | ||
867 | vcpu->arch.sie_block->gcr[reg] = val; | ||
868 | ga += 8; | ||
869 | if (reg == reg3) | 867 | if (reg == reg3) |
870 | break; | 868 | break; |
871 | reg = (reg + 1) % 16; | 869 | reg = (reg + 1) % 16; |
872 | } while (1); | 870 | } while (1); |
873 | 871 | kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu); | |
874 | return 0; | 872 | return 0; |
875 | } | 873 | } |
876 | 874 | ||
@@ -878,8 +876,9 @@ static int handle_stctg(struct kvm_vcpu *vcpu) | |||
878 | { | 876 | { |
879 | int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; | 877 | int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; |
880 | int reg3 = vcpu->arch.sie_block->ipa & 0x000f; | 878 | int reg3 = vcpu->arch.sie_block->ipa & 0x000f; |
881 | u64 ga, val; | 879 | int reg, rc, nr_regs; |
882 | int reg, rc; | 880 | u64 ctl_array[16]; |
881 | u64 ga; | ||
883 | 882 | ||
884 | vcpu->stat.instruction_stctg++; | 883 | vcpu->stat.instruction_stctg++; |
885 | 884 | ||
@@ -891,23 +890,19 @@ static int handle_stctg(struct kvm_vcpu *vcpu) | |||
891 | if (ga & 7) | 890 | if (ga & 7) |
892 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 891 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
893 | 892 | ||
894 | reg = reg1; | ||
895 | |||
896 | VCPU_EVENT(vcpu, 5, "stctg r1:%x, r3:%x, addr:%llx", reg1, reg3, ga); | 893 | VCPU_EVENT(vcpu, 5, "stctg r1:%x, r3:%x, addr:%llx", reg1, reg3, ga); |
897 | trace_kvm_s390_handle_stctl(vcpu, 1, reg1, reg3, ga); | 894 | trace_kvm_s390_handle_stctl(vcpu, 1, reg1, reg3, ga); |
898 | 895 | ||
896 | reg = reg1; | ||
897 | nr_regs = 0; | ||
899 | do { | 898 | do { |
900 | val = vcpu->arch.sie_block->gcr[reg]; | 899 | ctl_array[nr_regs++] = vcpu->arch.sie_block->gcr[reg]; |
901 | rc = write_guest(vcpu, ga, &val, sizeof(val)); | ||
902 | if (rc) | ||
903 | return kvm_s390_inject_prog_cond(vcpu, rc); | ||
904 | ga += 8; | ||
905 | if (reg == reg3) | 900 | if (reg == reg3) |
906 | break; | 901 | break; |
907 | reg = (reg + 1) % 16; | 902 | reg = (reg + 1) % 16; |
908 | } while (1); | 903 | } while (1); |
909 | 904 | rc = write_guest(vcpu, ga, ctl_array, nr_regs * sizeof(u64)); | |
910 | return 0; | 905 | return rc ? kvm_s390_inject_prog_cond(vcpu, rc) : 0; |
911 | } | 906 | } |
912 | 907 | ||
913 | static const intercept_handler_t eb_handlers[256] = { | 908 | static const intercept_handler_t eb_handlers[256] = { |
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index cf243ba3d50f..6651f9f73973 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c | |||
@@ -20,20 +20,13 @@ | |||
20 | #include "kvm-s390.h" | 20 | #include "kvm-s390.h" |
21 | #include "trace.h" | 21 | #include "trace.h" |
22 | 22 | ||
23 | static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr, | 23 | static int __sigp_sense(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu, |
24 | u64 *reg) | 24 | u64 *reg) |
25 | { | 25 | { |
26 | struct kvm_s390_local_interrupt *li; | 26 | struct kvm_s390_local_interrupt *li; |
27 | struct kvm_vcpu *dst_vcpu = NULL; | ||
28 | int cpuflags; | 27 | int cpuflags; |
29 | int rc; | 28 | int rc; |
30 | 29 | ||
31 | if (cpu_addr >= KVM_MAX_VCPUS) | ||
32 | return SIGP_CC_NOT_OPERATIONAL; | ||
33 | |||
34 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
35 | if (!dst_vcpu) | ||
36 | return SIGP_CC_NOT_OPERATIONAL; | ||
37 | li = &dst_vcpu->arch.local_int; | 30 | li = &dst_vcpu->arch.local_int; |
38 | 31 | ||
39 | cpuflags = atomic_read(li->cpuflags); | 32 | cpuflags = atomic_read(li->cpuflags); |
@@ -48,55 +41,53 @@ static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr, | |||
48 | rc = SIGP_CC_STATUS_STORED; | 41 | rc = SIGP_CC_STATUS_STORED; |
49 | } | 42 | } |
50 | 43 | ||
51 | VCPU_EVENT(vcpu, 4, "sensed status of cpu %x rc %x", cpu_addr, rc); | 44 | VCPU_EVENT(vcpu, 4, "sensed status of cpu %x rc %x", dst_vcpu->vcpu_id, |
45 | rc); | ||
52 | return rc; | 46 | return rc; |
53 | } | 47 | } |
54 | 48 | ||
55 | static int __sigp_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr) | 49 | static int __inject_sigp_emergency(struct kvm_vcpu *vcpu, |
50 | struct kvm_vcpu *dst_vcpu) | ||
56 | { | 51 | { |
57 | struct kvm_s390_interrupt s390int = { | 52 | struct kvm_s390_irq irq = { |
58 | .type = KVM_S390_INT_EMERGENCY, | 53 | .type = KVM_S390_INT_EMERGENCY, |
59 | .parm = vcpu->vcpu_id, | 54 | .u.emerg.code = vcpu->vcpu_id, |
60 | }; | 55 | }; |
61 | struct kvm_vcpu *dst_vcpu = NULL; | ||
62 | int rc = 0; | 56 | int rc = 0; |
63 | 57 | ||
64 | if (cpu_addr < KVM_MAX_VCPUS) | 58 | rc = kvm_s390_inject_vcpu(dst_vcpu, &irq); |
65 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
66 | if (!dst_vcpu) | ||
67 | return SIGP_CC_NOT_OPERATIONAL; | ||
68 | |||
69 | rc = kvm_s390_inject_vcpu(dst_vcpu, &s390int); | ||
70 | if (!rc) | 59 | if (!rc) |
71 | VCPU_EVENT(vcpu, 4, "sent sigp emerg to cpu %x", cpu_addr); | 60 | VCPU_EVENT(vcpu, 4, "sent sigp emerg to cpu %x", |
61 | dst_vcpu->vcpu_id); | ||
72 | 62 | ||
73 | return rc ? rc : SIGP_CC_ORDER_CODE_ACCEPTED; | 63 | return rc ? rc : SIGP_CC_ORDER_CODE_ACCEPTED; |
74 | } | 64 | } |
75 | 65 | ||
76 | static int __sigp_conditional_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr, | 66 | static int __sigp_emergency(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu) |
67 | { | ||
68 | return __inject_sigp_emergency(vcpu, dst_vcpu); | ||
69 | } | ||
70 | |||
71 | static int __sigp_conditional_emergency(struct kvm_vcpu *vcpu, | ||
72 | struct kvm_vcpu *dst_vcpu, | ||
77 | u16 asn, u64 *reg) | 73 | u16 asn, u64 *reg) |
78 | { | 74 | { |
79 | struct kvm_vcpu *dst_vcpu = NULL; | ||
80 | const u64 psw_int_mask = PSW_MASK_IO | PSW_MASK_EXT; | 75 | const u64 psw_int_mask = PSW_MASK_IO | PSW_MASK_EXT; |
81 | u16 p_asn, s_asn; | 76 | u16 p_asn, s_asn; |
82 | psw_t *psw; | 77 | psw_t *psw; |
83 | u32 flags; | 78 | u32 flags; |
84 | 79 | ||
85 | if (cpu_addr < KVM_MAX_VCPUS) | ||
86 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
87 | if (!dst_vcpu) | ||
88 | return SIGP_CC_NOT_OPERATIONAL; | ||
89 | flags = atomic_read(&dst_vcpu->arch.sie_block->cpuflags); | 80 | flags = atomic_read(&dst_vcpu->arch.sie_block->cpuflags); |
90 | psw = &dst_vcpu->arch.sie_block->gpsw; | 81 | psw = &dst_vcpu->arch.sie_block->gpsw; |
91 | p_asn = dst_vcpu->arch.sie_block->gcr[4] & 0xffff; /* Primary ASN */ | 82 | p_asn = dst_vcpu->arch.sie_block->gcr[4] & 0xffff; /* Primary ASN */ |
92 | s_asn = dst_vcpu->arch.sie_block->gcr[3] & 0xffff; /* Secondary ASN */ | 83 | s_asn = dst_vcpu->arch.sie_block->gcr[3] & 0xffff; /* Secondary ASN */ |
93 | 84 | ||
94 | /* Deliver the emergency signal? */ | 85 | /* Inject the emergency signal? */ |
95 | if (!(flags & CPUSTAT_STOPPED) | 86 | if (!(flags & CPUSTAT_STOPPED) |
96 | || (psw->mask & psw_int_mask) != psw_int_mask | 87 | || (psw->mask & psw_int_mask) != psw_int_mask |
97 | || ((flags & CPUSTAT_WAIT) && psw->addr != 0) | 88 | || ((flags & CPUSTAT_WAIT) && psw->addr != 0) |
98 | || (!(flags & CPUSTAT_WAIT) && (asn == p_asn || asn == s_asn))) { | 89 | || (!(flags & CPUSTAT_WAIT) && (asn == p_asn || asn == s_asn))) { |
99 | return __sigp_emergency(vcpu, cpu_addr); | 90 | return __inject_sigp_emergency(vcpu, dst_vcpu); |
100 | } else { | 91 | } else { |
101 | *reg &= 0xffffffff00000000UL; | 92 | *reg &= 0xffffffff00000000UL; |
102 | *reg |= SIGP_STATUS_INCORRECT_STATE; | 93 | *reg |= SIGP_STATUS_INCORRECT_STATE; |
@@ -104,23 +95,19 @@ static int __sigp_conditional_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr, | |||
104 | } | 95 | } |
105 | } | 96 | } |
106 | 97 | ||
107 | static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr) | 98 | static int __sigp_external_call(struct kvm_vcpu *vcpu, |
99 | struct kvm_vcpu *dst_vcpu) | ||
108 | { | 100 | { |
109 | struct kvm_s390_interrupt s390int = { | 101 | struct kvm_s390_irq irq = { |
110 | .type = KVM_S390_INT_EXTERNAL_CALL, | 102 | .type = KVM_S390_INT_EXTERNAL_CALL, |
111 | .parm = vcpu->vcpu_id, | 103 | .u.extcall.code = vcpu->vcpu_id, |
112 | }; | 104 | }; |
113 | struct kvm_vcpu *dst_vcpu = NULL; | ||
114 | int rc; | 105 | int rc; |
115 | 106 | ||
116 | if (cpu_addr < KVM_MAX_VCPUS) | 107 | rc = kvm_s390_inject_vcpu(dst_vcpu, &irq); |
117 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
118 | if (!dst_vcpu) | ||
119 | return SIGP_CC_NOT_OPERATIONAL; | ||
120 | |||
121 | rc = kvm_s390_inject_vcpu(dst_vcpu, &s390int); | ||
122 | if (!rc) | 108 | if (!rc) |
123 | VCPU_EVENT(vcpu, 4, "sent sigp ext call to cpu %x", cpu_addr); | 109 | VCPU_EVENT(vcpu, 4, "sent sigp ext call to cpu %x", |
110 | dst_vcpu->vcpu_id); | ||
124 | 111 | ||
125 | return rc ? rc : SIGP_CC_ORDER_CODE_ACCEPTED; | 112 | return rc ? rc : SIGP_CC_ORDER_CODE_ACCEPTED; |
126 | } | 113 | } |
@@ -128,29 +115,20 @@ static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr) | |||
128 | static int __inject_sigp_stop(struct kvm_vcpu *dst_vcpu, int action) | 115 | static int __inject_sigp_stop(struct kvm_vcpu *dst_vcpu, int action) |
129 | { | 116 | { |
130 | struct kvm_s390_local_interrupt *li = &dst_vcpu->arch.local_int; | 117 | struct kvm_s390_local_interrupt *li = &dst_vcpu->arch.local_int; |
131 | struct kvm_s390_interrupt_info *inti; | ||
132 | int rc = SIGP_CC_ORDER_CODE_ACCEPTED; | 118 | int rc = SIGP_CC_ORDER_CODE_ACCEPTED; |
133 | 119 | ||
134 | inti = kzalloc(sizeof(*inti), GFP_ATOMIC); | ||
135 | if (!inti) | ||
136 | return -ENOMEM; | ||
137 | inti->type = KVM_S390_SIGP_STOP; | ||
138 | |||
139 | spin_lock(&li->lock); | 120 | spin_lock(&li->lock); |
140 | if (li->action_bits & ACTION_STOP_ON_STOP) { | 121 | if (li->action_bits & ACTION_STOP_ON_STOP) { |
141 | /* another SIGP STOP is pending */ | 122 | /* another SIGP STOP is pending */ |
142 | kfree(inti); | ||
143 | rc = SIGP_CC_BUSY; | 123 | rc = SIGP_CC_BUSY; |
144 | goto out; | 124 | goto out; |
145 | } | 125 | } |
146 | if ((atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) { | 126 | if ((atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) { |
147 | kfree(inti); | ||
148 | if ((action & ACTION_STORE_ON_STOP) != 0) | 127 | if ((action & ACTION_STORE_ON_STOP) != 0) |
149 | rc = -ESHUTDOWN; | 128 | rc = -ESHUTDOWN; |
150 | goto out; | 129 | goto out; |
151 | } | 130 | } |
152 | list_add_tail(&inti->list, &li->list); | 131 | set_bit(IRQ_PEND_SIGP_STOP, &li->pending_irqs); |
153 | atomic_set(&li->active, 1); | ||
154 | li->action_bits |= action; | 132 | li->action_bits |= action; |
155 | atomic_set_mask(CPUSTAT_STOP_INT, li->cpuflags); | 133 | atomic_set_mask(CPUSTAT_STOP_INT, li->cpuflags); |
156 | kvm_s390_vcpu_wakeup(dst_vcpu); | 134 | kvm_s390_vcpu_wakeup(dst_vcpu); |
@@ -160,23 +138,27 @@ out: | |||
160 | return rc; | 138 | return rc; |
161 | } | 139 | } |
162 | 140 | ||
163 | static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int action) | 141 | static int __sigp_stop(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu) |
164 | { | 142 | { |
165 | struct kvm_vcpu *dst_vcpu = NULL; | ||
166 | int rc; | 143 | int rc; |
167 | 144 | ||
168 | if (cpu_addr >= KVM_MAX_VCPUS) | 145 | rc = __inject_sigp_stop(dst_vcpu, ACTION_STOP_ON_STOP); |
169 | return SIGP_CC_NOT_OPERATIONAL; | 146 | VCPU_EVENT(vcpu, 4, "sent sigp stop to cpu %x", dst_vcpu->vcpu_id); |
170 | 147 | ||
171 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | 148 | return rc; |
172 | if (!dst_vcpu) | 149 | } |
173 | return SIGP_CC_NOT_OPERATIONAL; | ||
174 | 150 | ||
175 | rc = __inject_sigp_stop(dst_vcpu, action); | 151 | static int __sigp_stop_and_store_status(struct kvm_vcpu *vcpu, |
152 | struct kvm_vcpu *dst_vcpu, u64 *reg) | ||
153 | { | ||
154 | int rc; | ||
176 | 155 | ||
177 | VCPU_EVENT(vcpu, 4, "sent sigp stop to cpu %x", cpu_addr); | 156 | rc = __inject_sigp_stop(dst_vcpu, ACTION_STOP_ON_STOP | |
157 | ACTION_STORE_ON_STOP); | ||
158 | VCPU_EVENT(vcpu, 4, "sent sigp stop and store status to cpu %x", | ||
159 | dst_vcpu->vcpu_id); | ||
178 | 160 | ||
179 | if ((action & ACTION_STORE_ON_STOP) != 0 && rc == -ESHUTDOWN) { | 161 | if (rc == -ESHUTDOWN) { |
180 | /* If the CPU has already been stopped, we still have | 162 | /* If the CPU has already been stopped, we still have |
181 | * to save the status when doing stop-and-store. This | 163 | * to save the status when doing stop-and-store. This |
182 | * has to be done after unlocking all spinlocks. */ | 164 | * has to be done after unlocking all spinlocks. */ |
@@ -212,18 +194,12 @@ static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter) | |||
212 | return rc; | 194 | return rc; |
213 | } | 195 | } |
214 | 196 | ||
215 | static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address, | 197 | static int __sigp_set_prefix(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu, |
216 | u64 *reg) | 198 | u32 address, u64 *reg) |
217 | { | 199 | { |
218 | struct kvm_s390_local_interrupt *li; | 200 | struct kvm_s390_local_interrupt *li; |
219 | struct kvm_vcpu *dst_vcpu = NULL; | ||
220 | struct kvm_s390_interrupt_info *inti; | ||
221 | int rc; | 201 | int rc; |
222 | 202 | ||
223 | if (cpu_addr < KVM_MAX_VCPUS) | ||
224 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
225 | if (!dst_vcpu) | ||
226 | return SIGP_CC_NOT_OPERATIONAL; | ||
227 | li = &dst_vcpu->arch.local_int; | 203 | li = &dst_vcpu->arch.local_int; |
228 | 204 | ||
229 | /* | 205 | /* |
@@ -238,46 +214,34 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address, | |||
238 | return SIGP_CC_STATUS_STORED; | 214 | return SIGP_CC_STATUS_STORED; |
239 | } | 215 | } |
240 | 216 | ||
241 | inti = kzalloc(sizeof(*inti), GFP_KERNEL); | ||
242 | if (!inti) | ||
243 | return SIGP_CC_BUSY; | ||
244 | |||
245 | spin_lock(&li->lock); | 217 | spin_lock(&li->lock); |
246 | /* cpu must be in stopped state */ | 218 | /* cpu must be in stopped state */ |
247 | if (!(atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) { | 219 | if (!(atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) { |
248 | *reg &= 0xffffffff00000000UL; | 220 | *reg &= 0xffffffff00000000UL; |
249 | *reg |= SIGP_STATUS_INCORRECT_STATE; | 221 | *reg |= SIGP_STATUS_INCORRECT_STATE; |
250 | rc = SIGP_CC_STATUS_STORED; | 222 | rc = SIGP_CC_STATUS_STORED; |
251 | kfree(inti); | ||
252 | goto out_li; | 223 | goto out_li; |
253 | } | 224 | } |
254 | 225 | ||
255 | inti->type = KVM_S390_SIGP_SET_PREFIX; | 226 | li->irq.prefix.address = address; |
256 | inti->prefix.address = address; | 227 | set_bit(IRQ_PEND_SET_PREFIX, &li->pending_irqs); |
257 | |||
258 | list_add_tail(&inti->list, &li->list); | ||
259 | atomic_set(&li->active, 1); | ||
260 | kvm_s390_vcpu_wakeup(dst_vcpu); | 228 | kvm_s390_vcpu_wakeup(dst_vcpu); |
261 | rc = SIGP_CC_ORDER_CODE_ACCEPTED; | 229 | rc = SIGP_CC_ORDER_CODE_ACCEPTED; |
262 | 230 | ||
263 | VCPU_EVENT(vcpu, 4, "set prefix of cpu %02x to %x", cpu_addr, address); | 231 | VCPU_EVENT(vcpu, 4, "set prefix of cpu %02x to %x", dst_vcpu->vcpu_id, |
232 | address); | ||
264 | out_li: | 233 | out_li: |
265 | spin_unlock(&li->lock); | 234 | spin_unlock(&li->lock); |
266 | return rc; | 235 | return rc; |
267 | } | 236 | } |
268 | 237 | ||
269 | static int __sigp_store_status_at_addr(struct kvm_vcpu *vcpu, u16 cpu_id, | 238 | static int __sigp_store_status_at_addr(struct kvm_vcpu *vcpu, |
270 | u32 addr, u64 *reg) | 239 | struct kvm_vcpu *dst_vcpu, |
240 | u32 addr, u64 *reg) | ||
271 | { | 241 | { |
272 | struct kvm_vcpu *dst_vcpu = NULL; | ||
273 | int flags; | 242 | int flags; |
274 | int rc; | 243 | int rc; |
275 | 244 | ||
276 | if (cpu_id < KVM_MAX_VCPUS) | ||
277 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_id); | ||
278 | if (!dst_vcpu) | ||
279 | return SIGP_CC_NOT_OPERATIONAL; | ||
280 | |||
281 | spin_lock(&dst_vcpu->arch.local_int.lock); | 245 | spin_lock(&dst_vcpu->arch.local_int.lock); |
282 | flags = atomic_read(dst_vcpu->arch.local_int.cpuflags); | 246 | flags = atomic_read(dst_vcpu->arch.local_int.cpuflags); |
283 | spin_unlock(&dst_vcpu->arch.local_int.lock); | 247 | spin_unlock(&dst_vcpu->arch.local_int.lock); |
@@ -297,19 +261,12 @@ static int __sigp_store_status_at_addr(struct kvm_vcpu *vcpu, u16 cpu_id, | |||
297 | return rc; | 261 | return rc; |
298 | } | 262 | } |
299 | 263 | ||
300 | static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr, | 264 | static int __sigp_sense_running(struct kvm_vcpu *vcpu, |
301 | u64 *reg) | 265 | struct kvm_vcpu *dst_vcpu, u64 *reg) |
302 | { | 266 | { |
303 | struct kvm_s390_local_interrupt *li; | 267 | struct kvm_s390_local_interrupt *li; |
304 | struct kvm_vcpu *dst_vcpu = NULL; | ||
305 | int rc; | 268 | int rc; |
306 | 269 | ||
307 | if (cpu_addr >= KVM_MAX_VCPUS) | ||
308 | return SIGP_CC_NOT_OPERATIONAL; | ||
309 | |||
310 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
311 | if (!dst_vcpu) | ||
312 | return SIGP_CC_NOT_OPERATIONAL; | ||
313 | li = &dst_vcpu->arch.local_int; | 270 | li = &dst_vcpu->arch.local_int; |
314 | if (atomic_read(li->cpuflags) & CPUSTAT_RUNNING) { | 271 | if (atomic_read(li->cpuflags) & CPUSTAT_RUNNING) { |
315 | /* running */ | 272 | /* running */ |
@@ -321,26 +278,19 @@ static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr, | |||
321 | rc = SIGP_CC_STATUS_STORED; | 278 | rc = SIGP_CC_STATUS_STORED; |
322 | } | 279 | } |
323 | 280 | ||
324 | VCPU_EVENT(vcpu, 4, "sensed running status of cpu %x rc %x", cpu_addr, | 281 | VCPU_EVENT(vcpu, 4, "sensed running status of cpu %x rc %x", |
325 | rc); | 282 | dst_vcpu->vcpu_id, rc); |
326 | 283 | ||
327 | return rc; | 284 | return rc; |
328 | } | 285 | } |
329 | 286 | ||
330 | /* Test whether the destination CPU is available and not busy */ | 287 | static int __prepare_sigp_re_start(struct kvm_vcpu *vcpu, |
331 | static int sigp_check_callable(struct kvm_vcpu *vcpu, u16 cpu_addr) | 288 | struct kvm_vcpu *dst_vcpu, u8 order_code) |
332 | { | 289 | { |
333 | struct kvm_s390_local_interrupt *li; | 290 | struct kvm_s390_local_interrupt *li = &dst_vcpu->arch.local_int; |
334 | int rc = SIGP_CC_ORDER_CODE_ACCEPTED; | 291 | /* handle (RE)START in user space */ |
335 | struct kvm_vcpu *dst_vcpu = NULL; | 292 | int rc = -EOPNOTSUPP; |
336 | |||
337 | if (cpu_addr >= KVM_MAX_VCPUS) | ||
338 | return SIGP_CC_NOT_OPERATIONAL; | ||
339 | 293 | ||
340 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
341 | if (!dst_vcpu) | ||
342 | return SIGP_CC_NOT_OPERATIONAL; | ||
343 | li = &dst_vcpu->arch.local_int; | ||
344 | spin_lock(&li->lock); | 294 | spin_lock(&li->lock); |
345 | if (li->action_bits & ACTION_STOP_ON_STOP) | 295 | if (li->action_bits & ACTION_STOP_ON_STOP) |
346 | rc = SIGP_CC_BUSY; | 296 | rc = SIGP_CC_BUSY; |
@@ -349,90 +299,131 @@ static int sigp_check_callable(struct kvm_vcpu *vcpu, u16 cpu_addr) | |||
349 | return rc; | 299 | return rc; |
350 | } | 300 | } |
351 | 301 | ||
352 | int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) | 302 | static int __prepare_sigp_cpu_reset(struct kvm_vcpu *vcpu, |
303 | struct kvm_vcpu *dst_vcpu, u8 order_code) | ||
353 | { | 304 | { |
354 | int r1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; | 305 | /* handle (INITIAL) CPU RESET in user space */ |
355 | int r3 = vcpu->arch.sie_block->ipa & 0x000f; | 306 | return -EOPNOTSUPP; |
356 | u32 parameter; | 307 | } |
357 | u16 cpu_addr = vcpu->run->s.regs.gprs[r3]; | ||
358 | u8 order_code; | ||
359 | int rc; | ||
360 | 308 | ||
361 | /* sigp in userspace can exit */ | 309 | static int __prepare_sigp_unknown(struct kvm_vcpu *vcpu, |
362 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | 310 | struct kvm_vcpu *dst_vcpu) |
363 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | 311 | { |
312 | /* handle unknown orders in user space */ | ||
313 | return -EOPNOTSUPP; | ||
314 | } | ||
364 | 315 | ||
365 | order_code = kvm_s390_get_base_disp_rs(vcpu); | 316 | static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code, |
317 | u16 cpu_addr, u32 parameter, u64 *status_reg) | ||
318 | { | ||
319 | int rc; | ||
320 | struct kvm_vcpu *dst_vcpu; | ||
366 | 321 | ||
367 | if (r1 % 2) | 322 | if (cpu_addr >= KVM_MAX_VCPUS) |
368 | parameter = vcpu->run->s.regs.gprs[r1]; | 323 | return SIGP_CC_NOT_OPERATIONAL; |
369 | else | 324 | |
370 | parameter = vcpu->run->s.regs.gprs[r1 + 1]; | 325 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); |
326 | if (!dst_vcpu) | ||
327 | return SIGP_CC_NOT_OPERATIONAL; | ||
371 | 328 | ||
372 | trace_kvm_s390_handle_sigp(vcpu, order_code, cpu_addr, parameter); | ||
373 | switch (order_code) { | 329 | switch (order_code) { |
374 | case SIGP_SENSE: | 330 | case SIGP_SENSE: |
375 | vcpu->stat.instruction_sigp_sense++; | 331 | vcpu->stat.instruction_sigp_sense++; |
376 | rc = __sigp_sense(vcpu, cpu_addr, | 332 | rc = __sigp_sense(vcpu, dst_vcpu, status_reg); |
377 | &vcpu->run->s.regs.gprs[r1]); | ||
378 | break; | 333 | break; |
379 | case SIGP_EXTERNAL_CALL: | 334 | case SIGP_EXTERNAL_CALL: |
380 | vcpu->stat.instruction_sigp_external_call++; | 335 | vcpu->stat.instruction_sigp_external_call++; |
381 | rc = __sigp_external_call(vcpu, cpu_addr); | 336 | rc = __sigp_external_call(vcpu, dst_vcpu); |
382 | break; | 337 | break; |
383 | case SIGP_EMERGENCY_SIGNAL: | 338 | case SIGP_EMERGENCY_SIGNAL: |
384 | vcpu->stat.instruction_sigp_emergency++; | 339 | vcpu->stat.instruction_sigp_emergency++; |
385 | rc = __sigp_emergency(vcpu, cpu_addr); | 340 | rc = __sigp_emergency(vcpu, dst_vcpu); |
386 | break; | 341 | break; |
387 | case SIGP_STOP: | 342 | case SIGP_STOP: |
388 | vcpu->stat.instruction_sigp_stop++; | 343 | vcpu->stat.instruction_sigp_stop++; |
389 | rc = __sigp_stop(vcpu, cpu_addr, ACTION_STOP_ON_STOP); | 344 | rc = __sigp_stop(vcpu, dst_vcpu); |
390 | break; | 345 | break; |
391 | case SIGP_STOP_AND_STORE_STATUS: | 346 | case SIGP_STOP_AND_STORE_STATUS: |
392 | vcpu->stat.instruction_sigp_stop++; | 347 | vcpu->stat.instruction_sigp_stop_store_status++; |
393 | rc = __sigp_stop(vcpu, cpu_addr, ACTION_STORE_ON_STOP | | 348 | rc = __sigp_stop_and_store_status(vcpu, dst_vcpu, status_reg); |
394 | ACTION_STOP_ON_STOP); | ||
395 | break; | 349 | break; |
396 | case SIGP_STORE_STATUS_AT_ADDRESS: | 350 | case SIGP_STORE_STATUS_AT_ADDRESS: |
397 | rc = __sigp_store_status_at_addr(vcpu, cpu_addr, parameter, | 351 | vcpu->stat.instruction_sigp_store_status++; |
398 | &vcpu->run->s.regs.gprs[r1]); | 352 | rc = __sigp_store_status_at_addr(vcpu, dst_vcpu, parameter, |
399 | break; | 353 | status_reg); |
400 | case SIGP_SET_ARCHITECTURE: | ||
401 | vcpu->stat.instruction_sigp_arch++; | ||
402 | rc = __sigp_set_arch(vcpu, parameter); | ||
403 | break; | 354 | break; |
404 | case SIGP_SET_PREFIX: | 355 | case SIGP_SET_PREFIX: |
405 | vcpu->stat.instruction_sigp_prefix++; | 356 | vcpu->stat.instruction_sigp_prefix++; |
406 | rc = __sigp_set_prefix(vcpu, cpu_addr, parameter, | 357 | rc = __sigp_set_prefix(vcpu, dst_vcpu, parameter, status_reg); |
407 | &vcpu->run->s.regs.gprs[r1]); | ||
408 | break; | 358 | break; |
409 | case SIGP_COND_EMERGENCY_SIGNAL: | 359 | case SIGP_COND_EMERGENCY_SIGNAL: |
410 | rc = __sigp_conditional_emergency(vcpu, cpu_addr, parameter, | 360 | vcpu->stat.instruction_sigp_cond_emergency++; |
411 | &vcpu->run->s.regs.gprs[r1]); | 361 | rc = __sigp_conditional_emergency(vcpu, dst_vcpu, parameter, |
362 | status_reg); | ||
412 | break; | 363 | break; |
413 | case SIGP_SENSE_RUNNING: | 364 | case SIGP_SENSE_RUNNING: |
414 | vcpu->stat.instruction_sigp_sense_running++; | 365 | vcpu->stat.instruction_sigp_sense_running++; |
415 | rc = __sigp_sense_running(vcpu, cpu_addr, | 366 | rc = __sigp_sense_running(vcpu, dst_vcpu, status_reg); |
416 | &vcpu->run->s.regs.gprs[r1]); | ||
417 | break; | 367 | break; |
418 | case SIGP_START: | 368 | case SIGP_START: |
419 | rc = sigp_check_callable(vcpu, cpu_addr); | 369 | vcpu->stat.instruction_sigp_start++; |
420 | if (rc == SIGP_CC_ORDER_CODE_ACCEPTED) | 370 | rc = __prepare_sigp_re_start(vcpu, dst_vcpu, order_code); |
421 | rc = -EOPNOTSUPP; /* Handle START in user space */ | ||
422 | break; | 371 | break; |
423 | case SIGP_RESTART: | 372 | case SIGP_RESTART: |
424 | vcpu->stat.instruction_sigp_restart++; | 373 | vcpu->stat.instruction_sigp_restart++; |
425 | rc = sigp_check_callable(vcpu, cpu_addr); | 374 | rc = __prepare_sigp_re_start(vcpu, dst_vcpu, order_code); |
426 | if (rc == SIGP_CC_ORDER_CODE_ACCEPTED) { | 375 | break; |
427 | VCPU_EVENT(vcpu, 4, | 376 | case SIGP_INITIAL_CPU_RESET: |
428 | "sigp restart %x to handle userspace", | 377 | vcpu->stat.instruction_sigp_init_cpu_reset++; |
429 | cpu_addr); | 378 | rc = __prepare_sigp_cpu_reset(vcpu, dst_vcpu, order_code); |
430 | /* user space must know about restart */ | 379 | break; |
431 | rc = -EOPNOTSUPP; | 380 | case SIGP_CPU_RESET: |
432 | } | 381 | vcpu->stat.instruction_sigp_cpu_reset++; |
382 | rc = __prepare_sigp_cpu_reset(vcpu, dst_vcpu, order_code); | ||
383 | break; | ||
384 | default: | ||
385 | vcpu->stat.instruction_sigp_unknown++; | ||
386 | rc = __prepare_sigp_unknown(vcpu, dst_vcpu); | ||
387 | } | ||
388 | |||
389 | if (rc == -EOPNOTSUPP) | ||
390 | VCPU_EVENT(vcpu, 4, | ||
391 | "sigp order %u -> cpu %x: handled in user space", | ||
392 | order_code, dst_vcpu->vcpu_id); | ||
393 | |||
394 | return rc; | ||
395 | } | ||
396 | |||
397 | int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) | ||
398 | { | ||
399 | int r1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; | ||
400 | int r3 = vcpu->arch.sie_block->ipa & 0x000f; | ||
401 | u32 parameter; | ||
402 | u16 cpu_addr = vcpu->run->s.regs.gprs[r3]; | ||
403 | u8 order_code; | ||
404 | int rc; | ||
405 | |||
406 | /* sigp in userspace can exit */ | ||
407 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | ||
408 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | ||
409 | |||
410 | order_code = kvm_s390_get_base_disp_rs(vcpu); | ||
411 | |||
412 | if (r1 % 2) | ||
413 | parameter = vcpu->run->s.regs.gprs[r1]; | ||
414 | else | ||
415 | parameter = vcpu->run->s.regs.gprs[r1 + 1]; | ||
416 | |||
417 | trace_kvm_s390_handle_sigp(vcpu, order_code, cpu_addr, parameter); | ||
418 | switch (order_code) { | ||
419 | case SIGP_SET_ARCHITECTURE: | ||
420 | vcpu->stat.instruction_sigp_arch++; | ||
421 | rc = __sigp_set_arch(vcpu, parameter); | ||
433 | break; | 422 | break; |
434 | default: | 423 | default: |
435 | return -EOPNOTSUPP; | 424 | rc = handle_sigp_dst(vcpu, order_code, cpu_addr, |
425 | parameter, | ||
426 | &vcpu->run->s.regs.gprs[r1]); | ||
436 | } | 427 | } |
437 | 428 | ||
438 | if (rc < 0) | 429 | if (rc < 0) |
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 71c7eff2c89f..be99357d238c 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
@@ -844,7 +844,7 @@ int set_guest_storage_key(struct mm_struct *mm, unsigned long addr, | |||
844 | 844 | ||
845 | down_read(&mm->mmap_sem); | 845 | down_read(&mm->mmap_sem); |
846 | retry: | 846 | retry: |
847 | ptep = get_locked_pte(current->mm, addr, &ptl); | 847 | ptep = get_locked_pte(mm, addr, &ptl); |
848 | if (unlikely(!ptep)) { | 848 | if (unlikely(!ptep)) { |
849 | up_read(&mm->mmap_sem); | 849 | up_read(&mm->mmap_sem); |
850 | return -EFAULT; | 850 | return -EFAULT; |
@@ -888,6 +888,45 @@ retry: | |||
888 | } | 888 | } |
889 | EXPORT_SYMBOL(set_guest_storage_key); | 889 | EXPORT_SYMBOL(set_guest_storage_key); |
890 | 890 | ||
891 | unsigned long get_guest_storage_key(struct mm_struct *mm, unsigned long addr) | ||
892 | { | ||
893 | spinlock_t *ptl; | ||
894 | pgste_t pgste; | ||
895 | pte_t *ptep; | ||
896 | uint64_t physaddr; | ||
897 | unsigned long key = 0; | ||
898 | |||
899 | down_read(&mm->mmap_sem); | ||
900 | ptep = get_locked_pte(mm, addr, &ptl); | ||
901 | if (unlikely(!ptep)) { | ||
902 | up_read(&mm->mmap_sem); | ||
903 | return -EFAULT; | ||
904 | } | ||
905 | pgste = pgste_get_lock(ptep); | ||
906 | |||
907 | if (pte_val(*ptep) & _PAGE_INVALID) { | ||
908 | key |= (pgste_val(pgste) & PGSTE_ACC_BITS) >> 56; | ||
909 | key |= (pgste_val(pgste) & PGSTE_FP_BIT) >> 56; | ||
910 | key |= (pgste_val(pgste) & PGSTE_GR_BIT) >> 48; | ||
911 | key |= (pgste_val(pgste) & PGSTE_GC_BIT) >> 48; | ||
912 | } else { | ||
913 | physaddr = pte_val(*ptep) & PAGE_MASK; | ||
914 | key = page_get_storage_key(physaddr); | ||
915 | |||
916 | /* Reflect guest's logical view, not physical */ | ||
917 | if (pgste_val(pgste) & PGSTE_GR_BIT) | ||
918 | key |= _PAGE_REFERENCED; | ||
919 | if (pgste_val(pgste) & PGSTE_GC_BIT) | ||
920 | key |= _PAGE_CHANGED; | ||
921 | } | ||
922 | |||
923 | pgste_set_unlock(ptep, pgste); | ||
924 | pte_unmap_unlock(ptep, ptl); | ||
925 | up_read(&mm->mmap_sem); | ||
926 | return key; | ||
927 | } | ||
928 | EXPORT_SYMBOL(get_guest_storage_key); | ||
929 | |||
891 | #else /* CONFIG_PGSTE */ | 930 | #else /* CONFIG_PGSTE */ |
892 | 931 | ||
893 | static inline int page_table_with_pgste(struct page *page) | 932 | static inline int page_table_with_pgste(struct page *page) |
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 6ed0c30d6a0c..d89c6b828c96 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -33,7 +33,7 @@ | |||
33 | 33 | ||
34 | #define KVM_MAX_VCPUS 255 | 34 | #define KVM_MAX_VCPUS 255 |
35 | #define KVM_SOFT_MAX_VCPUS 160 | 35 | #define KVM_SOFT_MAX_VCPUS 160 |
36 | #define KVM_USER_MEM_SLOTS 125 | 36 | #define KVM_USER_MEM_SLOTS 509 |
37 | /* memory slots that are not exposed to userspace */ | 37 | /* memory slots that are not exposed to userspace */ |
38 | #define KVM_PRIVATE_MEM_SLOTS 3 | 38 | #define KVM_PRIVATE_MEM_SLOTS 3 |
39 | #define KVM_MEM_SLOTS_NUM (KVM_USER_MEM_SLOTS + KVM_PRIVATE_MEM_SLOTS) | 39 | #define KVM_MEM_SLOTS_NUM (KVM_USER_MEM_SLOTS + KVM_PRIVATE_MEM_SLOTS) |
@@ -51,6 +51,7 @@ | |||
51 | | X86_CR0_NW | X86_CR0_CD | X86_CR0_PG)) | 51 | | X86_CR0_NW | X86_CR0_CD | X86_CR0_PG)) |
52 | 52 | ||
53 | #define CR3_L_MODE_RESERVED_BITS 0xFFFFFF0000000000ULL | 53 | #define CR3_L_MODE_RESERVED_BITS 0xFFFFFF0000000000ULL |
54 | #define CR3_PCID_INVD (1UL << 63) | ||
54 | #define CR4_RESERVED_BITS \ | 55 | #define CR4_RESERVED_BITS \ |
55 | (~(unsigned long)(X86_CR4_VME | X86_CR4_PVI | X86_CR4_TSD | X86_CR4_DE\ | 56 | (~(unsigned long)(X86_CR4_VME | X86_CR4_PVI | X86_CR4_TSD | X86_CR4_DE\ |
56 | | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE \ | 57 | | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE \ |
@@ -361,6 +362,7 @@ struct kvm_vcpu_arch { | |||
361 | int mp_state; | 362 | int mp_state; |
362 | u64 ia32_misc_enable_msr; | 363 | u64 ia32_misc_enable_msr; |
363 | bool tpr_access_reporting; | 364 | bool tpr_access_reporting; |
365 | u64 ia32_xss; | ||
364 | 366 | ||
365 | /* | 367 | /* |
366 | * Paging state of the vcpu | 368 | * Paging state of the vcpu |
@@ -542,7 +544,7 @@ struct kvm_apic_map { | |||
542 | struct rcu_head rcu; | 544 | struct rcu_head rcu; |
543 | u8 ldr_bits; | 545 | u8 ldr_bits; |
544 | /* fields bellow are used to decode ldr values in different modes */ | 546 | /* fields bellow are used to decode ldr values in different modes */ |
545 | u32 cid_shift, cid_mask, lid_mask; | 547 | u32 cid_shift, cid_mask, lid_mask, broadcast; |
546 | struct kvm_lapic *phys_map[256]; | 548 | struct kvm_lapic *phys_map[256]; |
547 | /* first index is cluster id second is cpu id in a cluster */ | 549 | /* first index is cluster id second is cpu id in a cluster */ |
548 | struct kvm_lapic *logical_map[16][16]; | 550 | struct kvm_lapic *logical_map[16][16]; |
@@ -602,6 +604,9 @@ struct kvm_arch { | |||
602 | 604 | ||
603 | struct kvm_xen_hvm_config xen_hvm_config; | 605 | struct kvm_xen_hvm_config xen_hvm_config; |
604 | 606 | ||
607 | /* reads protected by irq_srcu, writes by irq_lock */ | ||
608 | struct hlist_head mask_notifier_list; | ||
609 | |||
605 | /* fields used by HYPER-V emulation */ | 610 | /* fields used by HYPER-V emulation */ |
606 | u64 hv_guest_os_id; | 611 | u64 hv_guest_os_id; |
607 | u64 hv_hypercall; | 612 | u64 hv_hypercall; |
@@ -659,6 +664,16 @@ struct msr_data { | |||
659 | u64 data; | 664 | u64 data; |
660 | }; | 665 | }; |
661 | 666 | ||
667 | struct kvm_lapic_irq { | ||
668 | u32 vector; | ||
669 | u32 delivery_mode; | ||
670 | u32 dest_mode; | ||
671 | u32 level; | ||
672 | u32 trig_mode; | ||
673 | u32 shorthand; | ||
674 | u32 dest_id; | ||
675 | }; | ||
676 | |||
662 | struct kvm_x86_ops { | 677 | struct kvm_x86_ops { |
663 | int (*cpu_has_kvm_support)(void); /* __init */ | 678 | int (*cpu_has_kvm_support)(void); /* __init */ |
664 | int (*disabled_by_bios)(void); /* __init */ | 679 | int (*disabled_by_bios)(void); /* __init */ |
@@ -767,6 +782,7 @@ struct kvm_x86_ops { | |||
767 | enum x86_intercept_stage stage); | 782 | enum x86_intercept_stage stage); |
768 | void (*handle_external_intr)(struct kvm_vcpu *vcpu); | 783 | void (*handle_external_intr)(struct kvm_vcpu *vcpu); |
769 | bool (*mpx_supported)(void); | 784 | bool (*mpx_supported)(void); |
785 | bool (*xsaves_supported)(void); | ||
770 | 786 | ||
771 | int (*check_nested_events)(struct kvm_vcpu *vcpu, bool external_intr); | 787 | int (*check_nested_events)(struct kvm_vcpu *vcpu, bool external_intr); |
772 | 788 | ||
@@ -818,6 +834,19 @@ int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, | |||
818 | const void *val, int bytes); | 834 | const void *val, int bytes); |
819 | u8 kvm_get_guest_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn); | 835 | u8 kvm_get_guest_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn); |
820 | 836 | ||
837 | struct kvm_irq_mask_notifier { | ||
838 | void (*func)(struct kvm_irq_mask_notifier *kimn, bool masked); | ||
839 | int irq; | ||
840 | struct hlist_node link; | ||
841 | }; | ||
842 | |||
843 | void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq, | ||
844 | struct kvm_irq_mask_notifier *kimn); | ||
845 | void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq, | ||
846 | struct kvm_irq_mask_notifier *kimn); | ||
847 | void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin, | ||
848 | bool mask); | ||
849 | |||
821 | extern bool tdp_enabled; | 850 | extern bool tdp_enabled; |
822 | 851 | ||
823 | u64 vcpu_tsc_khz(struct kvm_vcpu *vcpu); | 852 | u64 vcpu_tsc_khz(struct kvm_vcpu *vcpu); |
@@ -863,7 +892,7 @@ int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu); | |||
863 | 892 | ||
864 | void kvm_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); | 893 | void kvm_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); |
865 | int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, int seg); | 894 | int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, int seg); |
866 | void kvm_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, unsigned int vector); | 895 | void kvm_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector); |
867 | 896 | ||
868 | int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int idt_index, | 897 | int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int idt_index, |
869 | int reason, bool has_error_code, u32 error_code); | 898 | int reason, bool has_error_code, u32 error_code); |
@@ -895,6 +924,7 @@ int kvm_read_guest_page_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, | |||
895 | gfn_t gfn, void *data, int offset, int len, | 924 | gfn_t gfn, void *data, int offset, int len, |
896 | u32 access); | 925 | u32 access); |
897 | bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl); | 926 | bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl); |
927 | bool kvm_require_dr(struct kvm_vcpu *vcpu, int dr); | ||
898 | 928 | ||
899 | static inline int __kvm_irq_line_state(unsigned long *irq_state, | 929 | static inline int __kvm_irq_line_state(unsigned long *irq_state, |
900 | int irq_source_id, int level) | 930 | int irq_source_id, int level) |
@@ -1066,6 +1096,7 @@ void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm, | |||
1066 | void kvm_define_shared_msr(unsigned index, u32 msr); | 1096 | void kvm_define_shared_msr(unsigned index, u32 msr); |
1067 | int kvm_set_shared_msr(unsigned index, u64 val, u64 mask); | 1097 | int kvm_set_shared_msr(unsigned index, u64 val, u64 mask); |
1068 | 1098 | ||
1099 | unsigned long kvm_get_linear_rip(struct kvm_vcpu *vcpu); | ||
1069 | bool kvm_is_linear_rip(struct kvm_vcpu *vcpu, unsigned long linear_rip); | 1100 | bool kvm_is_linear_rip(struct kvm_vcpu *vcpu, unsigned long linear_rip); |
1070 | 1101 | ||
1071 | void kvm_arch_async_page_not_present(struct kvm_vcpu *vcpu, | 1102 | void kvm_arch_async_page_not_present(struct kvm_vcpu *vcpu, |
diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index bcbfade26d8d..45afaee9555c 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h | |||
@@ -69,6 +69,7 @@ | |||
69 | #define SECONDARY_EXEC_PAUSE_LOOP_EXITING 0x00000400 | 69 | #define SECONDARY_EXEC_PAUSE_LOOP_EXITING 0x00000400 |
70 | #define SECONDARY_EXEC_ENABLE_INVPCID 0x00001000 | 70 | #define SECONDARY_EXEC_ENABLE_INVPCID 0x00001000 |
71 | #define SECONDARY_EXEC_SHADOW_VMCS 0x00004000 | 71 | #define SECONDARY_EXEC_SHADOW_VMCS 0x00004000 |
72 | #define SECONDARY_EXEC_XSAVES 0x00100000 | ||
72 | 73 | ||
73 | 74 | ||
74 | #define PIN_BASED_EXT_INTR_MASK 0x00000001 | 75 | #define PIN_BASED_EXT_INTR_MASK 0x00000001 |
@@ -159,6 +160,8 @@ enum vmcs_field { | |||
159 | EOI_EXIT_BITMAP3_HIGH = 0x00002023, | 160 | EOI_EXIT_BITMAP3_HIGH = 0x00002023, |
160 | VMREAD_BITMAP = 0x00002026, | 161 | VMREAD_BITMAP = 0x00002026, |
161 | VMWRITE_BITMAP = 0x00002028, | 162 | VMWRITE_BITMAP = 0x00002028, |
163 | XSS_EXIT_BITMAP = 0x0000202C, | ||
164 | XSS_EXIT_BITMAP_HIGH = 0x0000202D, | ||
162 | GUEST_PHYSICAL_ADDRESS = 0x00002400, | 165 | GUEST_PHYSICAL_ADDRESS = 0x00002400, |
163 | GUEST_PHYSICAL_ADDRESS_HIGH = 0x00002401, | 166 | GUEST_PHYSICAL_ADDRESS_HIGH = 0x00002401, |
164 | VMCS_LINK_POINTER = 0x00002800, | 167 | VMCS_LINK_POINTER = 0x00002800, |
diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h index 7e7a79ada658..5fa9770035dc 100644 --- a/arch/x86/include/asm/xsave.h +++ b/arch/x86/include/asm/xsave.h | |||
@@ -16,6 +16,7 @@ | |||
16 | #define XSTATE_Hi16_ZMM 0x80 | 16 | #define XSTATE_Hi16_ZMM 0x80 |
17 | 17 | ||
18 | #define XSTATE_FPSSE (XSTATE_FP | XSTATE_SSE) | 18 | #define XSTATE_FPSSE (XSTATE_FP | XSTATE_SSE) |
19 | #define XSTATE_AVX512 (XSTATE_OPMASK | XSTATE_ZMM_Hi256 | XSTATE_Hi16_ZMM) | ||
19 | /* Bit 63 of XCR0 is reserved for future expansion */ | 20 | /* Bit 63 of XCR0 is reserved for future expansion */ |
20 | #define XSTATE_EXTEND_MASK (~(XSTATE_FPSSE | (1ULL << 63))) | 21 | #define XSTATE_EXTEND_MASK (~(XSTATE_FPSSE | (1ULL << 63))) |
21 | 22 | ||
diff --git a/arch/x86/include/uapi/asm/vmx.h b/arch/x86/include/uapi/asm/vmx.h index 990a2fe1588d..b813bf9da1e2 100644 --- a/arch/x86/include/uapi/asm/vmx.h +++ b/arch/x86/include/uapi/asm/vmx.h | |||
@@ -72,6 +72,8 @@ | |||
72 | #define EXIT_REASON_XSETBV 55 | 72 | #define EXIT_REASON_XSETBV 55 |
73 | #define EXIT_REASON_APIC_WRITE 56 | 73 | #define EXIT_REASON_APIC_WRITE 56 |
74 | #define EXIT_REASON_INVPCID 58 | 74 | #define EXIT_REASON_INVPCID 58 |
75 | #define EXIT_REASON_XSAVES 63 | ||
76 | #define EXIT_REASON_XRSTORS 64 | ||
75 | 77 | ||
76 | #define VMX_EXIT_REASONS \ | 78 | #define VMX_EXIT_REASONS \ |
77 | { EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, \ | 79 | { EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, \ |
@@ -116,6 +118,8 @@ | |||
116 | { EXIT_REASON_INVALID_STATE, "INVALID_STATE" }, \ | 118 | { EXIT_REASON_INVALID_STATE, "INVALID_STATE" }, \ |
117 | { EXIT_REASON_INVD, "INVD" }, \ | 119 | { EXIT_REASON_INVD, "INVD" }, \ |
118 | { EXIT_REASON_INVVPID, "INVVPID" }, \ | 120 | { EXIT_REASON_INVVPID, "INVVPID" }, \ |
119 | { EXIT_REASON_INVPCID, "INVPCID" } | 121 | { EXIT_REASON_INVPCID, "INVPCID" }, \ |
122 | { EXIT_REASON_XSAVES, "XSAVES" }, \ | ||
123 | { EXIT_REASON_XRSTORS, "XRSTORS" } | ||
120 | 124 | ||
121 | #endif /* _UAPIVMX_H */ | 125 | #endif /* _UAPIVMX_H */ |
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index f6945bef2cd1..94f643484300 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c | |||
@@ -283,7 +283,14 @@ NOKPROBE_SYMBOL(do_async_page_fault); | |||
283 | static void __init paravirt_ops_setup(void) | 283 | static void __init paravirt_ops_setup(void) |
284 | { | 284 | { |
285 | pv_info.name = "KVM"; | 285 | pv_info.name = "KVM"; |
286 | pv_info.paravirt_enabled = 1; | 286 | |
287 | /* | ||
288 | * KVM isn't paravirt in the sense of paravirt_enabled. A KVM | ||
289 | * guest kernel works like a bare metal kernel with additional | ||
290 | * features, and paravirt_enabled is about features that are | ||
291 | * missing. | ||
292 | */ | ||
293 | pv_info.paravirt_enabled = 0; | ||
287 | 294 | ||
288 | if (kvm_para_has_feature(KVM_FEATURE_NOP_IO_DELAY)) | 295 | if (kvm_para_has_feature(KVM_FEATURE_NOP_IO_DELAY)) |
289 | pv_cpu_ops.io_delay = kvm_io_delay; | 296 | pv_cpu_ops.io_delay = kvm_io_delay; |
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index d9156ceecdff..42caaef897c8 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c | |||
@@ -59,13 +59,12 @@ static void kvm_get_wallclock(struct timespec *now) | |||
59 | 59 | ||
60 | native_write_msr(msr_kvm_wall_clock, low, high); | 60 | native_write_msr(msr_kvm_wall_clock, low, high); |
61 | 61 | ||
62 | preempt_disable(); | 62 | cpu = get_cpu(); |
63 | cpu = smp_processor_id(); | ||
64 | 63 | ||
65 | vcpu_time = &hv_clock[cpu].pvti; | 64 | vcpu_time = &hv_clock[cpu].pvti; |
66 | pvclock_read_wallclock(&wall_clock, vcpu_time, now); | 65 | pvclock_read_wallclock(&wall_clock, vcpu_time, now); |
67 | 66 | ||
68 | preempt_enable(); | 67 | put_cpu(); |
69 | } | 68 | } |
70 | 69 | ||
71 | static int kvm_set_wallclock(const struct timespec *now) | 70 | static int kvm_set_wallclock(const struct timespec *now) |
@@ -107,11 +106,10 @@ static unsigned long kvm_get_tsc_khz(void) | |||
107 | int cpu; | 106 | int cpu; |
108 | unsigned long tsc_khz; | 107 | unsigned long tsc_khz; |
109 | 108 | ||
110 | preempt_disable(); | 109 | cpu = get_cpu(); |
111 | cpu = smp_processor_id(); | ||
112 | src = &hv_clock[cpu].pvti; | 110 | src = &hv_clock[cpu].pvti; |
113 | tsc_khz = pvclock_tsc_khz(src); | 111 | tsc_khz = pvclock_tsc_khz(src); |
114 | preempt_enable(); | 112 | put_cpu(); |
115 | return tsc_khz; | 113 | return tsc_khz; |
116 | } | 114 | } |
117 | 115 | ||
@@ -263,7 +261,6 @@ void __init kvmclock_init(void) | |||
263 | #endif | 261 | #endif |
264 | kvm_get_preset_lpj(); | 262 | kvm_get_preset_lpj(); |
265 | clocksource_register_hz(&kvm_clock, NSEC_PER_SEC); | 263 | clocksource_register_hz(&kvm_clock, NSEC_PER_SEC); |
266 | pv_info.paravirt_enabled = 1; | ||
267 | pv_info.name = "KVM"; | 264 | pv_info.name = "KVM"; |
268 | 265 | ||
269 | if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE_STABLE_BIT)) | 266 | if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE_STABLE_BIT)) |
@@ -284,23 +281,22 @@ int __init kvm_setup_vsyscall_timeinfo(void) | |||
284 | 281 | ||
285 | size = PAGE_ALIGN(sizeof(struct pvclock_vsyscall_time_info)*NR_CPUS); | 282 | size = PAGE_ALIGN(sizeof(struct pvclock_vsyscall_time_info)*NR_CPUS); |
286 | 283 | ||
287 | preempt_disable(); | 284 | cpu = get_cpu(); |
288 | cpu = smp_processor_id(); | ||
289 | 285 | ||
290 | vcpu_time = &hv_clock[cpu].pvti; | 286 | vcpu_time = &hv_clock[cpu].pvti; |
291 | flags = pvclock_read_flags(vcpu_time); | 287 | flags = pvclock_read_flags(vcpu_time); |
292 | 288 | ||
293 | if (!(flags & PVCLOCK_TSC_STABLE_BIT)) { | 289 | if (!(flags & PVCLOCK_TSC_STABLE_BIT)) { |
294 | preempt_enable(); | 290 | put_cpu(); |
295 | return 1; | 291 | return 1; |
296 | } | 292 | } |
297 | 293 | ||
298 | if ((ret = pvclock_init_vsyscall(hv_clock, size))) { | 294 | if ((ret = pvclock_init_vsyscall(hv_clock, size))) { |
299 | preempt_enable(); | 295 | put_cpu(); |
300 | return ret; | 296 | return ret; |
301 | } | 297 | } |
302 | 298 | ||
303 | preempt_enable(); | 299 | put_cpu(); |
304 | 300 | ||
305 | kvm_clock.archdata.vclock_mode = VCLOCK_PVCLOCK; | 301 | kvm_clock.archdata.vclock_mode = VCLOCK_PVCLOCK; |
306 | #endif | 302 | #endif |
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c index 4c540c4719d8..0de1fae2bdf0 100644 --- a/arch/x86/kernel/xsave.c +++ b/arch/x86/kernel/xsave.c | |||
@@ -738,3 +738,4 @@ void *get_xsave_addr(struct xsave_struct *xsave, int xstate) | |||
738 | 738 | ||
739 | return (void *)xsave + xstate_comp_offsets[feature]; | 739 | return (void *)xsave + xstate_comp_offsets[feature]; |
740 | } | 740 | } |
741 | EXPORT_SYMBOL_GPL(get_xsave_addr); | ||
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index 25d22b2d6509..08f790dfadc9 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile | |||
@@ -7,14 +7,13 @@ CFLAGS_vmx.o := -I. | |||
7 | 7 | ||
8 | KVM := ../../../virt/kvm | 8 | KVM := ../../../virt/kvm |
9 | 9 | ||
10 | kvm-y += $(KVM)/kvm_main.o $(KVM)/ioapic.o \ | 10 | kvm-y += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \ |
11 | $(KVM)/coalesced_mmio.o $(KVM)/irq_comm.o \ | ||
12 | $(KVM)/eventfd.o $(KVM)/irqchip.o $(KVM)/vfio.o | 11 | $(KVM)/eventfd.o $(KVM)/irqchip.o $(KVM)/vfio.o |
13 | kvm-$(CONFIG_KVM_DEVICE_ASSIGNMENT) += $(KVM)/assigned-dev.o $(KVM)/iommu.o | ||
14 | kvm-$(CONFIG_KVM_ASYNC_PF) += $(KVM)/async_pf.o | 12 | kvm-$(CONFIG_KVM_ASYNC_PF) += $(KVM)/async_pf.o |
15 | 13 | ||
16 | kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \ | 14 | kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \ |
17 | i8254.o cpuid.o pmu.o | 15 | i8254.o ioapic.o irq_comm.o cpuid.o pmu.o |
16 | kvm-$(CONFIG_KVM_DEVICE_ASSIGNMENT) += assigned-dev.o iommu.o | ||
18 | kvm-intel-y += vmx.o | 17 | kvm-intel-y += vmx.o |
19 | kvm-amd-y += svm.o | 18 | kvm-amd-y += svm.o |
20 | 19 | ||
diff --git a/virt/kvm/assigned-dev.c b/arch/x86/kvm/assigned-dev.c index e05000e200d2..6eb5c20ee373 100644 --- a/virt/kvm/assigned-dev.c +++ b/arch/x86/kvm/assigned-dev.c | |||
@@ -20,6 +20,32 @@ | |||
20 | #include <linux/namei.h> | 20 | #include <linux/namei.h> |
21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
22 | #include "irq.h" | 22 | #include "irq.h" |
23 | #include "assigned-dev.h" | ||
24 | |||
25 | struct kvm_assigned_dev_kernel { | ||
26 | struct kvm_irq_ack_notifier ack_notifier; | ||
27 | struct list_head list; | ||
28 | int assigned_dev_id; | ||
29 | int host_segnr; | ||
30 | int host_busnr; | ||
31 | int host_devfn; | ||
32 | unsigned int entries_nr; | ||
33 | int host_irq; | ||
34 | bool host_irq_disabled; | ||
35 | bool pci_2_3; | ||
36 | struct msix_entry *host_msix_entries; | ||
37 | int guest_irq; | ||
38 | struct msix_entry *guest_msix_entries; | ||
39 | unsigned long irq_requested_type; | ||
40 | int irq_source_id; | ||
41 | int flags; | ||
42 | struct pci_dev *dev; | ||
43 | struct kvm *kvm; | ||
44 | spinlock_t intx_lock; | ||
45 | spinlock_t intx_mask_lock; | ||
46 | char irq_name[32]; | ||
47 | struct pci_saved_state *pci_saved_state; | ||
48 | }; | ||
23 | 49 | ||
24 | static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *head, | 50 | static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *head, |
25 | int assigned_dev_id) | 51 | int assigned_dev_id) |
@@ -748,7 +774,7 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, | |||
748 | if (r) | 774 | if (r) |
749 | goto out_list_del; | 775 | goto out_list_del; |
750 | } | 776 | } |
751 | r = kvm_assign_device(kvm, match); | 777 | r = kvm_assign_device(kvm, match->dev); |
752 | if (r) | 778 | if (r) |
753 | goto out_list_del; | 779 | goto out_list_del; |
754 | 780 | ||
@@ -790,7 +816,7 @@ static int kvm_vm_ioctl_deassign_device(struct kvm *kvm, | |||
790 | goto out; | 816 | goto out; |
791 | } | 817 | } |
792 | 818 | ||
793 | kvm_deassign_device(kvm, match); | 819 | kvm_deassign_device(kvm, match->dev); |
794 | 820 | ||
795 | kvm_free_assigned_device(kvm, match); | 821 | kvm_free_assigned_device(kvm, match); |
796 | 822 | ||
diff --git a/arch/x86/kvm/assigned-dev.h b/arch/x86/kvm/assigned-dev.h new file mode 100644 index 000000000000..a428c1a211b2 --- /dev/null +++ b/arch/x86/kvm/assigned-dev.h | |||
@@ -0,0 +1,32 @@ | |||
1 | #ifndef ARCH_X86_KVM_ASSIGNED_DEV_H | ||
2 | #define ARCH_X86_KVM_ASSIGNED_DEV_H | ||
3 | |||
4 | #include <linux/kvm_host.h> | ||
5 | |||
6 | #ifdef CONFIG_KVM_DEVICE_ASSIGNMENT | ||
7 | int kvm_assign_device(struct kvm *kvm, struct pci_dev *pdev); | ||
8 | int kvm_deassign_device(struct kvm *kvm, struct pci_dev *pdev); | ||
9 | |||
10 | int kvm_iommu_map_guest(struct kvm *kvm); | ||
11 | int kvm_iommu_unmap_guest(struct kvm *kvm); | ||
12 | |||
13 | long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl, | ||
14 | unsigned long arg); | ||
15 | |||
16 | void kvm_free_all_assigned_devices(struct kvm *kvm); | ||
17 | #else | ||
18 | static inline int kvm_iommu_unmap_guest(struct kvm *kvm) | ||
19 | { | ||
20 | return 0; | ||
21 | } | ||
22 | |||
23 | static inline long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl, | ||
24 | unsigned long arg) | ||
25 | { | ||
26 | return -ENOTTY; | ||
27 | } | ||
28 | |||
29 | static inline void kvm_free_all_assigned_devices(struct kvm *kvm) {} | ||
30 | #endif /* CONFIG_KVM_DEVICE_ASSIGNMENT */ | ||
31 | |||
32 | #endif /* ARCH_X86_KVM_ASSIGNED_DEV_H */ | ||
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 976e3a57f9ea..8a80737ee6e6 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include "mmu.h" | 23 | #include "mmu.h" |
24 | #include "trace.h" | 24 | #include "trace.h" |
25 | 25 | ||
26 | static u32 xstate_required_size(u64 xstate_bv) | 26 | static u32 xstate_required_size(u64 xstate_bv, bool compacted) |
27 | { | 27 | { |
28 | int feature_bit = 0; | 28 | int feature_bit = 0; |
29 | u32 ret = XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET; | 29 | u32 ret = XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET; |
@@ -31,9 +31,10 @@ static u32 xstate_required_size(u64 xstate_bv) | |||
31 | xstate_bv &= XSTATE_EXTEND_MASK; | 31 | xstate_bv &= XSTATE_EXTEND_MASK; |
32 | while (xstate_bv) { | 32 | while (xstate_bv) { |
33 | if (xstate_bv & 0x1) { | 33 | if (xstate_bv & 0x1) { |
34 | u32 eax, ebx, ecx, edx; | 34 | u32 eax, ebx, ecx, edx, offset; |
35 | cpuid_count(0xD, feature_bit, &eax, &ebx, &ecx, &edx); | 35 | cpuid_count(0xD, feature_bit, &eax, &ebx, &ecx, &edx); |
36 | ret = max(ret, eax + ebx); | 36 | offset = compacted ? ret : ebx; |
37 | ret = max(ret, offset + eax); | ||
37 | } | 38 | } |
38 | 39 | ||
39 | xstate_bv >>= 1; | 40 | xstate_bv >>= 1; |
@@ -53,6 +54,8 @@ u64 kvm_supported_xcr0(void) | |||
53 | return xcr0; | 54 | return xcr0; |
54 | } | 55 | } |
55 | 56 | ||
57 | #define F(x) bit(X86_FEATURE_##x) | ||
58 | |||
56 | int kvm_update_cpuid(struct kvm_vcpu *vcpu) | 59 | int kvm_update_cpuid(struct kvm_vcpu *vcpu) |
57 | { | 60 | { |
58 | struct kvm_cpuid_entry2 *best; | 61 | struct kvm_cpuid_entry2 *best; |
@@ -64,13 +67,13 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu) | |||
64 | 67 | ||
65 | /* Update OSXSAVE bit */ | 68 | /* Update OSXSAVE bit */ |
66 | if (cpu_has_xsave && best->function == 0x1) { | 69 | if (cpu_has_xsave && best->function == 0x1) { |
67 | best->ecx &= ~(bit(X86_FEATURE_OSXSAVE)); | 70 | best->ecx &= ~F(OSXSAVE); |
68 | if (kvm_read_cr4_bits(vcpu, X86_CR4_OSXSAVE)) | 71 | if (kvm_read_cr4_bits(vcpu, X86_CR4_OSXSAVE)) |
69 | best->ecx |= bit(X86_FEATURE_OSXSAVE); | 72 | best->ecx |= F(OSXSAVE); |
70 | } | 73 | } |
71 | 74 | ||
72 | if (apic) { | 75 | if (apic) { |
73 | if (best->ecx & bit(X86_FEATURE_TSC_DEADLINE_TIMER)) | 76 | if (best->ecx & F(TSC_DEADLINE_TIMER)) |
74 | apic->lapic_timer.timer_mode_mask = 3 << 17; | 77 | apic->lapic_timer.timer_mode_mask = 3 << 17; |
75 | else | 78 | else |
76 | apic->lapic_timer.timer_mode_mask = 1 << 17; | 79 | apic->lapic_timer.timer_mode_mask = 1 << 17; |
@@ -85,9 +88,13 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu) | |||
85 | (best->eax | ((u64)best->edx << 32)) & | 88 | (best->eax | ((u64)best->edx << 32)) & |
86 | kvm_supported_xcr0(); | 89 | kvm_supported_xcr0(); |
87 | vcpu->arch.guest_xstate_size = best->ebx = | 90 | vcpu->arch.guest_xstate_size = best->ebx = |
88 | xstate_required_size(vcpu->arch.xcr0); | 91 | xstate_required_size(vcpu->arch.xcr0, false); |
89 | } | 92 | } |
90 | 93 | ||
94 | best = kvm_find_cpuid_entry(vcpu, 0xD, 1); | ||
95 | if (best && (best->eax & (F(XSAVES) | F(XSAVEC)))) | ||
96 | best->ebx = xstate_required_size(vcpu->arch.xcr0, true); | ||
97 | |||
91 | /* | 98 | /* |
92 | * The existing code assumes virtual address is 48-bit in the canonical | 99 | * The existing code assumes virtual address is 48-bit in the canonical |
93 | * address checks; exit if it is ever changed. | 100 | * address checks; exit if it is ever changed. |
@@ -122,8 +129,8 @@ static void cpuid_fix_nx_cap(struct kvm_vcpu *vcpu) | |||
122 | break; | 129 | break; |
123 | } | 130 | } |
124 | } | 131 | } |
125 | if (entry && (entry->edx & bit(X86_FEATURE_NX)) && !is_efer_nx()) { | 132 | if (entry && (entry->edx & F(NX)) && !is_efer_nx()) { |
126 | entry->edx &= ~bit(X86_FEATURE_NX); | 133 | entry->edx &= ~F(NX); |
127 | printk(KERN_INFO "kvm: guest NX capability removed\n"); | 134 | printk(KERN_INFO "kvm: guest NX capability removed\n"); |
128 | } | 135 | } |
129 | } | 136 | } |
@@ -227,8 +234,6 @@ static void do_cpuid_1_ent(struct kvm_cpuid_entry2 *entry, u32 function, | |||
227 | entry->flags = 0; | 234 | entry->flags = 0; |
228 | } | 235 | } |
229 | 236 | ||
230 | #define F(x) bit(X86_FEATURE_##x) | ||
231 | |||
232 | static int __do_cpuid_ent_emulated(struct kvm_cpuid_entry2 *entry, | 237 | static int __do_cpuid_ent_emulated(struct kvm_cpuid_entry2 *entry, |
233 | u32 func, u32 index, int *nent, int maxnent) | 238 | u32 func, u32 index, int *nent, int maxnent) |
234 | { | 239 | { |
@@ -267,6 +272,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, | |||
267 | unsigned f_rdtscp = kvm_x86_ops->rdtscp_supported() ? F(RDTSCP) : 0; | 272 | unsigned f_rdtscp = kvm_x86_ops->rdtscp_supported() ? F(RDTSCP) : 0; |
268 | unsigned f_invpcid = kvm_x86_ops->invpcid_supported() ? F(INVPCID) : 0; | 273 | unsigned f_invpcid = kvm_x86_ops->invpcid_supported() ? F(INVPCID) : 0; |
269 | unsigned f_mpx = kvm_x86_ops->mpx_supported() ? F(MPX) : 0; | 274 | unsigned f_mpx = kvm_x86_ops->mpx_supported() ? F(MPX) : 0; |
275 | unsigned f_xsaves = kvm_x86_ops->xsaves_supported() ? F(XSAVES) : 0; | ||
270 | 276 | ||
271 | /* cpuid 1.edx */ | 277 | /* cpuid 1.edx */ |
272 | const u32 kvm_supported_word0_x86_features = | 278 | const u32 kvm_supported_word0_x86_features = |
@@ -317,7 +323,12 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, | |||
317 | const u32 kvm_supported_word9_x86_features = | 323 | const u32 kvm_supported_word9_x86_features = |
318 | F(FSGSBASE) | F(BMI1) | F(HLE) | F(AVX2) | F(SMEP) | | 324 | F(FSGSBASE) | F(BMI1) | F(HLE) | F(AVX2) | F(SMEP) | |
319 | F(BMI2) | F(ERMS) | f_invpcid | F(RTM) | f_mpx | F(RDSEED) | | 325 | F(BMI2) | F(ERMS) | f_invpcid | F(RTM) | f_mpx | F(RDSEED) | |
320 | F(ADX) | F(SMAP); | 326 | F(ADX) | F(SMAP) | F(AVX512F) | F(AVX512PF) | F(AVX512ER) | |
327 | F(AVX512CD); | ||
328 | |||
329 | /* cpuid 0xD.1.eax */ | ||
330 | const u32 kvm_supported_word10_x86_features = | ||
331 | F(XSAVEOPT) | F(XSAVEC) | F(XGETBV1) | f_xsaves; | ||
321 | 332 | ||
322 | /* all calls to cpuid_count() should be made on the same cpu */ | 333 | /* all calls to cpuid_count() should be made on the same cpu */ |
323 | get_cpu(); | 334 | get_cpu(); |
@@ -453,16 +464,34 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, | |||
453 | u64 supported = kvm_supported_xcr0(); | 464 | u64 supported = kvm_supported_xcr0(); |
454 | 465 | ||
455 | entry->eax &= supported; | 466 | entry->eax &= supported; |
467 | entry->ebx = xstate_required_size(supported, false); | ||
468 | entry->ecx = entry->ebx; | ||
456 | entry->edx &= supported >> 32; | 469 | entry->edx &= supported >> 32; |
457 | entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX; | 470 | entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX; |
471 | if (!supported) | ||
472 | break; | ||
473 | |||
458 | for (idx = 1, i = 1; idx < 64; ++idx) { | 474 | for (idx = 1, i = 1; idx < 64; ++idx) { |
459 | u64 mask = ((u64)1 << idx); | 475 | u64 mask = ((u64)1 << idx); |
460 | if (*nent >= maxnent) | 476 | if (*nent >= maxnent) |
461 | goto out; | 477 | goto out; |
462 | 478 | ||
463 | do_cpuid_1_ent(&entry[i], function, idx); | 479 | do_cpuid_1_ent(&entry[i], function, idx); |
464 | if (entry[i].eax == 0 || !(supported & mask)) | 480 | if (idx == 1) { |
465 | continue; | 481 | entry[i].eax &= kvm_supported_word10_x86_features; |
482 | entry[i].ebx = 0; | ||
483 | if (entry[i].eax & (F(XSAVES)|F(XSAVEC))) | ||
484 | entry[i].ebx = | ||
485 | xstate_required_size(supported, | ||
486 | true); | ||
487 | } else { | ||
488 | if (entry[i].eax == 0 || !(supported & mask)) | ||
489 | continue; | ||
490 | if (WARN_ON_ONCE(entry[i].ecx & 1)) | ||
491 | continue; | ||
492 | } | ||
493 | entry[i].ecx = 0; | ||
494 | entry[i].edx = 0; | ||
466 | entry[i].flags |= | 495 | entry[i].flags |= |
467 | KVM_CPUID_FLAG_SIGNIFCANT_INDEX; | 496 | KVM_CPUID_FLAG_SIGNIFCANT_INDEX; |
468 | ++*nent; | 497 | ++*nent; |
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 9f8a2faf5040..169b09d76ddd 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -123,6 +123,7 @@ | |||
123 | #define Prefix (3<<15) /* Instruction varies with 66/f2/f3 prefix */ | 123 | #define Prefix (3<<15) /* Instruction varies with 66/f2/f3 prefix */ |
124 | #define RMExt (4<<15) /* Opcode extension in ModRM r/m if mod == 3 */ | 124 | #define RMExt (4<<15) /* Opcode extension in ModRM r/m if mod == 3 */ |
125 | #define Escape (5<<15) /* Escape to coprocessor instruction */ | 125 | #define Escape (5<<15) /* Escape to coprocessor instruction */ |
126 | #define InstrDual (6<<15) /* Alternate instruction decoding of mod == 3 */ | ||
126 | #define Sse (1<<18) /* SSE Vector instruction */ | 127 | #define Sse (1<<18) /* SSE Vector instruction */ |
127 | /* Generic ModRM decode. */ | 128 | /* Generic ModRM decode. */ |
128 | #define ModRM (1<<19) | 129 | #define ModRM (1<<19) |
@@ -166,6 +167,8 @@ | |||
166 | #define CheckPerm ((u64)1 << 49) /* Has valid check_perm field */ | 167 | #define CheckPerm ((u64)1 << 49) /* Has valid check_perm field */ |
167 | #define NoBigReal ((u64)1 << 50) /* No big real mode */ | 168 | #define NoBigReal ((u64)1 << 50) /* No big real mode */ |
168 | #define PrivUD ((u64)1 << 51) /* #UD instead of #GP on CPL > 0 */ | 169 | #define PrivUD ((u64)1 << 51) /* #UD instead of #GP on CPL > 0 */ |
170 | #define NearBranch ((u64)1 << 52) /* Near branches */ | ||
171 | #define No16 ((u64)1 << 53) /* No 16 bit operand */ | ||
169 | 172 | ||
170 | #define DstXacc (DstAccLo | SrcAccHi | SrcWrite) | 173 | #define DstXacc (DstAccLo | SrcAccHi | SrcWrite) |
171 | 174 | ||
@@ -209,6 +212,7 @@ struct opcode { | |||
209 | const struct group_dual *gdual; | 212 | const struct group_dual *gdual; |
210 | const struct gprefix *gprefix; | 213 | const struct gprefix *gprefix; |
211 | const struct escape *esc; | 214 | const struct escape *esc; |
215 | const struct instr_dual *idual; | ||
212 | void (*fastop)(struct fastop *fake); | 216 | void (*fastop)(struct fastop *fake); |
213 | } u; | 217 | } u; |
214 | int (*check_perm)(struct x86_emulate_ctxt *ctxt); | 218 | int (*check_perm)(struct x86_emulate_ctxt *ctxt); |
@@ -231,6 +235,11 @@ struct escape { | |||
231 | struct opcode high[64]; | 235 | struct opcode high[64]; |
232 | }; | 236 | }; |
233 | 237 | ||
238 | struct instr_dual { | ||
239 | struct opcode mod012; | ||
240 | struct opcode mod3; | ||
241 | }; | ||
242 | |||
234 | /* EFLAGS bit definitions. */ | 243 | /* EFLAGS bit definitions. */ |
235 | #define EFLG_ID (1<<21) | 244 | #define EFLG_ID (1<<21) |
236 | #define EFLG_VIP (1<<20) | 245 | #define EFLG_VIP (1<<20) |
@@ -379,6 +388,15 @@ static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *)); | |||
379 | ON64(FOP2E(op##q, rax, cl)) \ | 388 | ON64(FOP2E(op##q, rax, cl)) \ |
380 | FOP_END | 389 | FOP_END |
381 | 390 | ||
391 | /* 2 operand, src and dest are reversed */ | ||
392 | #define FASTOP2R(op, name) \ | ||
393 | FOP_START(name) \ | ||
394 | FOP2E(op##b, dl, al) \ | ||
395 | FOP2E(op##w, dx, ax) \ | ||
396 | FOP2E(op##l, edx, eax) \ | ||
397 | ON64(FOP2E(op##q, rdx, rax)) \ | ||
398 | FOP_END | ||
399 | |||
382 | #define FOP3E(op, dst, src, src2) \ | 400 | #define FOP3E(op, dst, src, src2) \ |
383 | FOP_ALIGN #op " %" #src2 ", %" #src ", %" #dst " \n\t" FOP_RET | 401 | FOP_ALIGN #op " %" #src2 ", %" #src ", %" #dst " \n\t" FOP_RET |
384 | 402 | ||
@@ -477,9 +495,9 @@ address_mask(struct x86_emulate_ctxt *ctxt, unsigned long reg) | |||
477 | } | 495 | } |
478 | 496 | ||
479 | static inline unsigned long | 497 | static inline unsigned long |
480 | register_address(struct x86_emulate_ctxt *ctxt, unsigned long reg) | 498 | register_address(struct x86_emulate_ctxt *ctxt, int reg) |
481 | { | 499 | { |
482 | return address_mask(ctxt, reg); | 500 | return address_mask(ctxt, reg_read(ctxt, reg)); |
483 | } | 501 | } |
484 | 502 | ||
485 | static void masked_increment(ulong *reg, ulong mask, int inc) | 503 | static void masked_increment(ulong *reg, ulong mask, int inc) |
@@ -488,7 +506,7 @@ static void masked_increment(ulong *reg, ulong mask, int inc) | |||
488 | } | 506 | } |
489 | 507 | ||
490 | static inline void | 508 | static inline void |
491 | register_address_increment(struct x86_emulate_ctxt *ctxt, unsigned long *reg, int inc) | 509 | register_address_increment(struct x86_emulate_ctxt *ctxt, int reg, int inc) |
492 | { | 510 | { |
493 | ulong mask; | 511 | ulong mask; |
494 | 512 | ||
@@ -496,7 +514,7 @@ register_address_increment(struct x86_emulate_ctxt *ctxt, unsigned long *reg, in | |||
496 | mask = ~0UL; | 514 | mask = ~0UL; |
497 | else | 515 | else |
498 | mask = ad_mask(ctxt); | 516 | mask = ad_mask(ctxt); |
499 | masked_increment(reg, mask, inc); | 517 | masked_increment(reg_rmw(ctxt, reg), mask, inc); |
500 | } | 518 | } |
501 | 519 | ||
502 | static void rsp_increment(struct x86_emulate_ctxt *ctxt, int inc) | 520 | static void rsp_increment(struct x86_emulate_ctxt *ctxt, int inc) |
@@ -564,40 +582,6 @@ static int emulate_nm(struct x86_emulate_ctxt *ctxt) | |||
564 | return emulate_exception(ctxt, NM_VECTOR, 0, false); | 582 | return emulate_exception(ctxt, NM_VECTOR, 0, false); |
565 | } | 583 | } |
566 | 584 | ||
567 | static inline int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst, | ||
568 | int cs_l) | ||
569 | { | ||
570 | switch (ctxt->op_bytes) { | ||
571 | case 2: | ||
572 | ctxt->_eip = (u16)dst; | ||
573 | break; | ||
574 | case 4: | ||
575 | ctxt->_eip = (u32)dst; | ||
576 | break; | ||
577 | #ifdef CONFIG_X86_64 | ||
578 | case 8: | ||
579 | if ((cs_l && is_noncanonical_address(dst)) || | ||
580 | (!cs_l && (dst >> 32) != 0)) | ||
581 | return emulate_gp(ctxt, 0); | ||
582 | ctxt->_eip = dst; | ||
583 | break; | ||
584 | #endif | ||
585 | default: | ||
586 | WARN(1, "unsupported eip assignment size\n"); | ||
587 | } | ||
588 | return X86EMUL_CONTINUE; | ||
589 | } | ||
590 | |||
591 | static inline int assign_eip_near(struct x86_emulate_ctxt *ctxt, ulong dst) | ||
592 | { | ||
593 | return assign_eip_far(ctxt, dst, ctxt->mode == X86EMUL_MODE_PROT64); | ||
594 | } | ||
595 | |||
596 | static inline int jmp_rel(struct x86_emulate_ctxt *ctxt, int rel) | ||
597 | { | ||
598 | return assign_eip_near(ctxt, ctxt->_eip + rel); | ||
599 | } | ||
600 | |||
601 | static u16 get_segment_selector(struct x86_emulate_ctxt *ctxt, unsigned seg) | 585 | static u16 get_segment_selector(struct x86_emulate_ctxt *ctxt, unsigned seg) |
602 | { | 586 | { |
603 | u16 selector; | 587 | u16 selector; |
@@ -641,25 +625,24 @@ static bool insn_aligned(struct x86_emulate_ctxt *ctxt, unsigned size) | |||
641 | return true; | 625 | return true; |
642 | } | 626 | } |
643 | 627 | ||
644 | static int __linearize(struct x86_emulate_ctxt *ctxt, | 628 | static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt, |
645 | struct segmented_address addr, | 629 | struct segmented_address addr, |
646 | unsigned *max_size, unsigned size, | 630 | unsigned *max_size, unsigned size, |
647 | bool write, bool fetch, | 631 | bool write, bool fetch, |
648 | ulong *linear) | 632 | enum x86emul_mode mode, ulong *linear) |
649 | { | 633 | { |
650 | struct desc_struct desc; | 634 | struct desc_struct desc; |
651 | bool usable; | 635 | bool usable; |
652 | ulong la; | 636 | ulong la; |
653 | u32 lim; | 637 | u32 lim; |
654 | u16 sel; | 638 | u16 sel; |
655 | unsigned cpl; | ||
656 | 639 | ||
657 | la = seg_base(ctxt, addr.seg) + addr.ea; | 640 | la = seg_base(ctxt, addr.seg) + addr.ea; |
658 | *max_size = 0; | 641 | *max_size = 0; |
659 | switch (ctxt->mode) { | 642 | switch (mode) { |
660 | case X86EMUL_MODE_PROT64: | 643 | case X86EMUL_MODE_PROT64: |
661 | if (((signed long)la << 16) >> 16 != la) | 644 | if (is_noncanonical_address(la)) |
662 | return emulate_gp(ctxt, 0); | 645 | goto bad; |
663 | 646 | ||
664 | *max_size = min_t(u64, ~0u, (1ull << 48) - la); | 647 | *max_size = min_t(u64, ~0u, (1ull << 48) - la); |
665 | if (size > *max_size) | 648 | if (size > *max_size) |
@@ -678,46 +661,20 @@ static int __linearize(struct x86_emulate_ctxt *ctxt, | |||
678 | if (!fetch && (desc.type & 8) && !(desc.type & 2)) | 661 | if (!fetch && (desc.type & 8) && !(desc.type & 2)) |
679 | goto bad; | 662 | goto bad; |
680 | lim = desc_limit_scaled(&desc); | 663 | lim = desc_limit_scaled(&desc); |
681 | if ((ctxt->mode == X86EMUL_MODE_REAL) && !fetch && | 664 | if (!(desc.type & 8) && (desc.type & 4)) { |
682 | (ctxt->d & NoBigReal)) { | ||
683 | /* la is between zero and 0xffff */ | ||
684 | if (la > 0xffff) | ||
685 | goto bad; | ||
686 | *max_size = 0x10000 - la; | ||
687 | } else if ((desc.type & 8) || !(desc.type & 4)) { | ||
688 | /* expand-up segment */ | ||
689 | if (addr.ea > lim) | ||
690 | goto bad; | ||
691 | *max_size = min_t(u64, ~0u, (u64)lim + 1 - addr.ea); | ||
692 | } else { | ||
693 | /* expand-down segment */ | 665 | /* expand-down segment */ |
694 | if (addr.ea <= lim) | 666 | if (addr.ea <= lim) |
695 | goto bad; | 667 | goto bad; |
696 | lim = desc.d ? 0xffffffff : 0xffff; | 668 | lim = desc.d ? 0xffffffff : 0xffff; |
697 | if (addr.ea > lim) | ||
698 | goto bad; | ||
699 | *max_size = min_t(u64, ~0u, (u64)lim + 1 - addr.ea); | ||
700 | } | 669 | } |
670 | if (addr.ea > lim) | ||
671 | goto bad; | ||
672 | *max_size = min_t(u64, ~0u, (u64)lim + 1 - addr.ea); | ||
701 | if (size > *max_size) | 673 | if (size > *max_size) |
702 | goto bad; | 674 | goto bad; |
703 | cpl = ctxt->ops->cpl(ctxt); | 675 | la &= (u32)-1; |
704 | if (!(desc.type & 8)) { | ||
705 | /* data segment */ | ||
706 | if (cpl > desc.dpl) | ||
707 | goto bad; | ||
708 | } else if ((desc.type & 8) && !(desc.type & 4)) { | ||
709 | /* nonconforming code segment */ | ||
710 | if (cpl != desc.dpl) | ||
711 | goto bad; | ||
712 | } else if ((desc.type & 8) && (desc.type & 4)) { | ||
713 | /* conforming code segment */ | ||
714 | if (cpl < desc.dpl) | ||
715 | goto bad; | ||
716 | } | ||
717 | break; | 676 | break; |
718 | } | 677 | } |
719 | if (fetch ? ctxt->mode != X86EMUL_MODE_PROT64 : ctxt->ad_bytes != 8) | ||
720 | la &= (u32)-1; | ||
721 | if (insn_aligned(ctxt, size) && ((la & (size - 1)) != 0)) | 678 | if (insn_aligned(ctxt, size) && ((la & (size - 1)) != 0)) |
722 | return emulate_gp(ctxt, 0); | 679 | return emulate_gp(ctxt, 0); |
723 | *linear = la; | 680 | *linear = la; |
@@ -735,9 +692,55 @@ static int linearize(struct x86_emulate_ctxt *ctxt, | |||
735 | ulong *linear) | 692 | ulong *linear) |
736 | { | 693 | { |
737 | unsigned max_size; | 694 | unsigned max_size; |
738 | return __linearize(ctxt, addr, &max_size, size, write, false, linear); | 695 | return __linearize(ctxt, addr, &max_size, size, write, false, |
696 | ctxt->mode, linear); | ||
697 | } | ||
698 | |||
699 | static inline int assign_eip(struct x86_emulate_ctxt *ctxt, ulong dst, | ||
700 | enum x86emul_mode mode) | ||
701 | { | ||
702 | ulong linear; | ||
703 | int rc; | ||
704 | unsigned max_size; | ||
705 | struct segmented_address addr = { .seg = VCPU_SREG_CS, | ||
706 | .ea = dst }; | ||
707 | |||
708 | if (ctxt->op_bytes != sizeof(unsigned long)) | ||
709 | addr.ea = dst & ((1UL << (ctxt->op_bytes << 3)) - 1); | ||
710 | rc = __linearize(ctxt, addr, &max_size, 1, false, true, mode, &linear); | ||
711 | if (rc == X86EMUL_CONTINUE) | ||
712 | ctxt->_eip = addr.ea; | ||
713 | return rc; | ||
714 | } | ||
715 | |||
716 | static inline int assign_eip_near(struct x86_emulate_ctxt *ctxt, ulong dst) | ||
717 | { | ||
718 | return assign_eip(ctxt, dst, ctxt->mode); | ||
739 | } | 719 | } |
740 | 720 | ||
721 | static int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst, | ||
722 | const struct desc_struct *cs_desc) | ||
723 | { | ||
724 | enum x86emul_mode mode = ctxt->mode; | ||
725 | |||
726 | #ifdef CONFIG_X86_64 | ||
727 | if (ctxt->mode >= X86EMUL_MODE_PROT32 && cs_desc->l) { | ||
728 | u64 efer = 0; | ||
729 | |||
730 | ctxt->ops->get_msr(ctxt, MSR_EFER, &efer); | ||
731 | if (efer & EFER_LMA) | ||
732 | mode = X86EMUL_MODE_PROT64; | ||
733 | } | ||
734 | #endif | ||
735 | if (mode == X86EMUL_MODE_PROT16 || mode == X86EMUL_MODE_PROT32) | ||
736 | mode = cs_desc->d ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16; | ||
737 | return assign_eip(ctxt, dst, mode); | ||
738 | } | ||
739 | |||
740 | static inline int jmp_rel(struct x86_emulate_ctxt *ctxt, int rel) | ||
741 | { | ||
742 | return assign_eip_near(ctxt, ctxt->_eip + rel); | ||
743 | } | ||
741 | 744 | ||
742 | static int segmented_read_std(struct x86_emulate_ctxt *ctxt, | 745 | static int segmented_read_std(struct x86_emulate_ctxt *ctxt, |
743 | struct segmented_address addr, | 746 | struct segmented_address addr, |
@@ -776,7 +779,8 @@ static int __do_insn_fetch_bytes(struct x86_emulate_ctxt *ctxt, int op_size) | |||
776 | * boundary check itself. Instead, we use max_size to check | 779 | * boundary check itself. Instead, we use max_size to check |
777 | * against op_size. | 780 | * against op_size. |
778 | */ | 781 | */ |
779 | rc = __linearize(ctxt, addr, &max_size, 0, false, true, &linear); | 782 | rc = __linearize(ctxt, addr, &max_size, 0, false, true, ctxt->mode, |
783 | &linear); | ||
780 | if (unlikely(rc != X86EMUL_CONTINUE)) | 784 | if (unlikely(rc != X86EMUL_CONTINUE)) |
781 | return rc; | 785 | return rc; |
782 | 786 | ||
@@ -911,6 +915,8 @@ FASTOP2W(btc); | |||
911 | 915 | ||
912 | FASTOP2(xadd); | 916 | FASTOP2(xadd); |
913 | 917 | ||
918 | FASTOP2R(cmp, cmp_r); | ||
919 | |||
914 | static u8 test_cc(unsigned int condition, unsigned long flags) | 920 | static u8 test_cc(unsigned int condition, unsigned long flags) |
915 | { | 921 | { |
916 | u8 rc; | 922 | u8 rc; |
@@ -1221,6 +1227,7 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, | |||
1221 | if (index_reg != 4) | 1227 | if (index_reg != 4) |
1222 | modrm_ea += reg_read(ctxt, index_reg) << scale; | 1228 | modrm_ea += reg_read(ctxt, index_reg) << scale; |
1223 | } else if ((ctxt->modrm_rm & 7) == 5 && ctxt->modrm_mod == 0) { | 1229 | } else if ((ctxt->modrm_rm & 7) == 5 && ctxt->modrm_mod == 0) { |
1230 | modrm_ea += insn_fetch(s32, ctxt); | ||
1224 | if (ctxt->mode == X86EMUL_MODE_PROT64) | 1231 | if (ctxt->mode == X86EMUL_MODE_PROT64) |
1225 | ctxt->rip_relative = 1; | 1232 | ctxt->rip_relative = 1; |
1226 | } else { | 1233 | } else { |
@@ -1229,10 +1236,6 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, | |||
1229 | adjust_modrm_seg(ctxt, base_reg); | 1236 | adjust_modrm_seg(ctxt, base_reg); |
1230 | } | 1237 | } |
1231 | switch (ctxt->modrm_mod) { | 1238 | switch (ctxt->modrm_mod) { |
1232 | case 0: | ||
1233 | if (ctxt->modrm_rm == 5) | ||
1234 | modrm_ea += insn_fetch(s32, ctxt); | ||
1235 | break; | ||
1236 | case 1: | 1239 | case 1: |
1237 | modrm_ea += insn_fetch(s8, ctxt); | 1240 | modrm_ea += insn_fetch(s8, ctxt); |
1238 | break; | 1241 | break; |
@@ -1284,7 +1287,8 @@ static void fetch_bit_operand(struct x86_emulate_ctxt *ctxt) | |||
1284 | else | 1287 | else |
1285 | sv = (s64)ctxt->src.val & (s64)mask; | 1288 | sv = (s64)ctxt->src.val & (s64)mask; |
1286 | 1289 | ||
1287 | ctxt->dst.addr.mem.ea += (sv >> 3); | 1290 | ctxt->dst.addr.mem.ea = address_mask(ctxt, |
1291 | ctxt->dst.addr.mem.ea + (sv >> 3)); | ||
1288 | } | 1292 | } |
1289 | 1293 | ||
1290 | /* only subword offset */ | 1294 | /* only subword offset */ |
@@ -1610,6 +1614,9 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt, | |||
1610 | sizeof(base3), &ctxt->exception); | 1614 | sizeof(base3), &ctxt->exception); |
1611 | if (ret != X86EMUL_CONTINUE) | 1615 | if (ret != X86EMUL_CONTINUE) |
1612 | return ret; | 1616 | return ret; |
1617 | if (is_noncanonical_address(get_desc_base(&seg_desc) | | ||
1618 | ((u64)base3 << 32))) | ||
1619 | return emulate_gp(ctxt, 0); | ||
1613 | } | 1620 | } |
1614 | load: | 1621 | load: |
1615 | ctxt->ops->set_segment(ctxt, selector, &seg_desc, base3, seg); | 1622 | ctxt->ops->set_segment(ctxt, selector, &seg_desc, base3, seg); |
@@ -1807,6 +1814,10 @@ static int em_push_sreg(struct x86_emulate_ctxt *ctxt) | |||
1807 | int seg = ctxt->src2.val; | 1814 | int seg = ctxt->src2.val; |
1808 | 1815 | ||
1809 | ctxt->src.val = get_segment_selector(ctxt, seg); | 1816 | ctxt->src.val = get_segment_selector(ctxt, seg); |
1817 | if (ctxt->op_bytes == 4) { | ||
1818 | rsp_increment(ctxt, -2); | ||
1819 | ctxt->op_bytes = 2; | ||
1820 | } | ||
1810 | 1821 | ||
1811 | return em_push(ctxt); | 1822 | return em_push(ctxt); |
1812 | } | 1823 | } |
@@ -1850,7 +1861,7 @@ static int em_pusha(struct x86_emulate_ctxt *ctxt) | |||
1850 | 1861 | ||
1851 | static int em_pushf(struct x86_emulate_ctxt *ctxt) | 1862 | static int em_pushf(struct x86_emulate_ctxt *ctxt) |
1852 | { | 1863 | { |
1853 | ctxt->src.val = (unsigned long)ctxt->eflags; | 1864 | ctxt->src.val = (unsigned long)ctxt->eflags & ~EFLG_VM; |
1854 | return em_push(ctxt); | 1865 | return em_push(ctxt); |
1855 | } | 1866 | } |
1856 | 1867 | ||
@@ -2035,7 +2046,7 @@ static int em_jmp_far(struct x86_emulate_ctxt *ctxt) | |||
2035 | if (rc != X86EMUL_CONTINUE) | 2046 | if (rc != X86EMUL_CONTINUE) |
2036 | return rc; | 2047 | return rc; |
2037 | 2048 | ||
2038 | rc = assign_eip_far(ctxt, ctxt->src.val, new_desc.l); | 2049 | rc = assign_eip_far(ctxt, ctxt->src.val, &new_desc); |
2039 | if (rc != X86EMUL_CONTINUE) { | 2050 | if (rc != X86EMUL_CONTINUE) { |
2040 | WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64); | 2051 | WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64); |
2041 | /* assigning eip failed; restore the old cs */ | 2052 | /* assigning eip failed; restore the old cs */ |
@@ -2045,31 +2056,22 @@ static int em_jmp_far(struct x86_emulate_ctxt *ctxt) | |||
2045 | return rc; | 2056 | return rc; |
2046 | } | 2057 | } |
2047 | 2058 | ||
2048 | static int em_grp45(struct x86_emulate_ctxt *ctxt) | 2059 | static int em_jmp_abs(struct x86_emulate_ctxt *ctxt) |
2049 | { | 2060 | { |
2050 | int rc = X86EMUL_CONTINUE; | 2061 | return assign_eip_near(ctxt, ctxt->src.val); |
2062 | } | ||
2051 | 2063 | ||
2052 | switch (ctxt->modrm_reg) { | 2064 | static int em_call_near_abs(struct x86_emulate_ctxt *ctxt) |
2053 | case 2: /* call near abs */ { | 2065 | { |
2054 | long int old_eip; | 2066 | int rc; |
2055 | old_eip = ctxt->_eip; | 2067 | long int old_eip; |
2056 | rc = assign_eip_near(ctxt, ctxt->src.val); | 2068 | |
2057 | if (rc != X86EMUL_CONTINUE) | 2069 | old_eip = ctxt->_eip; |
2058 | break; | 2070 | rc = assign_eip_near(ctxt, ctxt->src.val); |
2059 | ctxt->src.val = old_eip; | 2071 | if (rc != X86EMUL_CONTINUE) |
2060 | rc = em_push(ctxt); | 2072 | return rc; |
2061 | break; | 2073 | ctxt->src.val = old_eip; |
2062 | } | 2074 | rc = em_push(ctxt); |
2063 | case 4: /* jmp abs */ | ||
2064 | rc = assign_eip_near(ctxt, ctxt->src.val); | ||
2065 | break; | ||
2066 | case 5: /* jmp far */ | ||
2067 | rc = em_jmp_far(ctxt); | ||
2068 | break; | ||
2069 | case 6: /* push */ | ||
2070 | rc = em_push(ctxt); | ||
2071 | break; | ||
2072 | } | ||
2073 | return rc; | 2075 | return rc; |
2074 | } | 2076 | } |
2075 | 2077 | ||
@@ -2128,11 +2130,11 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt) | |||
2128 | /* Outer-privilege level return is not implemented */ | 2130 | /* Outer-privilege level return is not implemented */ |
2129 | if (ctxt->mode >= X86EMUL_MODE_PROT16 && (cs & 3) > cpl) | 2131 | if (ctxt->mode >= X86EMUL_MODE_PROT16 && (cs & 3) > cpl) |
2130 | return X86EMUL_UNHANDLEABLE; | 2132 | return X86EMUL_UNHANDLEABLE; |
2131 | rc = __load_segment_descriptor(ctxt, (u16)cs, VCPU_SREG_CS, 0, false, | 2133 | rc = __load_segment_descriptor(ctxt, (u16)cs, VCPU_SREG_CS, cpl, false, |
2132 | &new_desc); | 2134 | &new_desc); |
2133 | if (rc != X86EMUL_CONTINUE) | 2135 | if (rc != X86EMUL_CONTINUE) |
2134 | return rc; | 2136 | return rc; |
2135 | rc = assign_eip_far(ctxt, eip, new_desc.l); | 2137 | rc = assign_eip_far(ctxt, eip, &new_desc); |
2136 | if (rc != X86EMUL_CONTINUE) { | 2138 | if (rc != X86EMUL_CONTINUE) { |
2137 | WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64); | 2139 | WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64); |
2138 | ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS); | 2140 | ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS); |
@@ -2316,6 +2318,7 @@ static int em_syscall(struct x86_emulate_ctxt *ctxt) | |||
2316 | 2318 | ||
2317 | ops->get_msr(ctxt, MSR_SYSCALL_MASK, &msr_data); | 2319 | ops->get_msr(ctxt, MSR_SYSCALL_MASK, &msr_data); |
2318 | ctxt->eflags &= ~msr_data; | 2320 | ctxt->eflags &= ~msr_data; |
2321 | ctxt->eflags |= EFLG_RESERVED_ONE_MASK; | ||
2319 | #endif | 2322 | #endif |
2320 | } else { | 2323 | } else { |
2321 | /* legacy mode */ | 2324 | /* legacy mode */ |
@@ -2349,11 +2352,9 @@ static int em_sysenter(struct x86_emulate_ctxt *ctxt) | |||
2349 | && !vendor_intel(ctxt)) | 2352 | && !vendor_intel(ctxt)) |
2350 | return emulate_ud(ctxt); | 2353 | return emulate_ud(ctxt); |
2351 | 2354 | ||
2352 | /* XXX sysenter/sysexit have not been tested in 64bit mode. | 2355 | /* sysenter/sysexit have not been tested in 64bit mode. */ |
2353 | * Therefore, we inject an #UD. | ||
2354 | */ | ||
2355 | if (ctxt->mode == X86EMUL_MODE_PROT64) | 2356 | if (ctxt->mode == X86EMUL_MODE_PROT64) |
2356 | return emulate_ud(ctxt); | 2357 | return X86EMUL_UNHANDLEABLE; |
2357 | 2358 | ||
2358 | setup_syscalls_segments(ctxt, &cs, &ss); | 2359 | setup_syscalls_segments(ctxt, &cs, &ss); |
2359 | 2360 | ||
@@ -2425,6 +2426,8 @@ static int em_sysexit(struct x86_emulate_ctxt *ctxt) | |||
2425 | if ((msr_data & 0xfffc) == 0x0) | 2426 | if ((msr_data & 0xfffc) == 0x0) |
2426 | return emulate_gp(ctxt, 0); | 2427 | return emulate_gp(ctxt, 0); |
2427 | ss_sel = (u16)(msr_data + 24); | 2428 | ss_sel = (u16)(msr_data + 24); |
2429 | rcx = (u32)rcx; | ||
2430 | rdx = (u32)rdx; | ||
2428 | break; | 2431 | break; |
2429 | case X86EMUL_MODE_PROT64: | 2432 | case X86EMUL_MODE_PROT64: |
2430 | cs_sel = (u16)(msr_data + 32); | 2433 | cs_sel = (u16)(msr_data + 32); |
@@ -2599,7 +2602,6 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt, | |||
2599 | ret = ops->read_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg, | 2602 | ret = ops->read_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg, |
2600 | &ctxt->exception); | 2603 | &ctxt->exception); |
2601 | if (ret != X86EMUL_CONTINUE) | 2604 | if (ret != X86EMUL_CONTINUE) |
2602 | /* FIXME: need to provide precise fault address */ | ||
2603 | return ret; | 2605 | return ret; |
2604 | 2606 | ||
2605 | save_state_to_tss16(ctxt, &tss_seg); | 2607 | save_state_to_tss16(ctxt, &tss_seg); |
@@ -2607,13 +2609,11 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt, | |||
2607 | ret = ops->write_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg, | 2609 | ret = ops->write_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg, |
2608 | &ctxt->exception); | 2610 | &ctxt->exception); |
2609 | if (ret != X86EMUL_CONTINUE) | 2611 | if (ret != X86EMUL_CONTINUE) |
2610 | /* FIXME: need to provide precise fault address */ | ||
2611 | return ret; | 2612 | return ret; |
2612 | 2613 | ||
2613 | ret = ops->read_std(ctxt, new_tss_base, &tss_seg, sizeof tss_seg, | 2614 | ret = ops->read_std(ctxt, new_tss_base, &tss_seg, sizeof tss_seg, |
2614 | &ctxt->exception); | 2615 | &ctxt->exception); |
2615 | if (ret != X86EMUL_CONTINUE) | 2616 | if (ret != X86EMUL_CONTINUE) |
2616 | /* FIXME: need to provide precise fault address */ | ||
2617 | return ret; | 2617 | return ret; |
2618 | 2618 | ||
2619 | if (old_tss_sel != 0xffff) { | 2619 | if (old_tss_sel != 0xffff) { |
@@ -2624,7 +2624,6 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt, | |||
2624 | sizeof tss_seg.prev_task_link, | 2624 | sizeof tss_seg.prev_task_link, |
2625 | &ctxt->exception); | 2625 | &ctxt->exception); |
2626 | if (ret != X86EMUL_CONTINUE) | 2626 | if (ret != X86EMUL_CONTINUE) |
2627 | /* FIXME: need to provide precise fault address */ | ||
2628 | return ret; | 2627 | return ret; |
2629 | } | 2628 | } |
2630 | 2629 | ||
@@ -2813,7 +2812,8 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt, | |||
2813 | * | 2812 | * |
2814 | * 1. jmp/call/int to task gate: Check against DPL of the task gate | 2813 | * 1. jmp/call/int to task gate: Check against DPL of the task gate |
2815 | * 2. Exception/IRQ/iret: No check is performed | 2814 | * 2. Exception/IRQ/iret: No check is performed |
2816 | * 3. jmp/call to TSS: Check against DPL of the TSS | 2815 | * 3. jmp/call to TSS/task-gate: No check is performed since the |
2816 | * hardware checks it before exiting. | ||
2817 | */ | 2817 | */ |
2818 | if (reason == TASK_SWITCH_GATE) { | 2818 | if (reason == TASK_SWITCH_GATE) { |
2819 | if (idt_index != -1) { | 2819 | if (idt_index != -1) { |
@@ -2830,13 +2830,8 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt, | |||
2830 | if ((tss_selector & 3) > dpl || ops->cpl(ctxt) > dpl) | 2830 | if ((tss_selector & 3) > dpl || ops->cpl(ctxt) > dpl) |
2831 | return emulate_gp(ctxt, (idt_index << 3) | 0x2); | 2831 | return emulate_gp(ctxt, (idt_index << 3) | 0x2); |
2832 | } | 2832 | } |
2833 | } else if (reason != TASK_SWITCH_IRET) { | ||
2834 | int dpl = next_tss_desc.dpl; | ||
2835 | if ((tss_selector & 3) > dpl || ops->cpl(ctxt) > dpl) | ||
2836 | return emulate_gp(ctxt, tss_selector); | ||
2837 | } | 2833 | } |
2838 | 2834 | ||
2839 | |||
2840 | desc_limit = desc_limit_scaled(&next_tss_desc); | 2835 | desc_limit = desc_limit_scaled(&next_tss_desc); |
2841 | if (!next_tss_desc.p || | 2836 | if (!next_tss_desc.p || |
2842 | ((desc_limit < 0x67 && (next_tss_desc.type & 8)) || | 2837 | ((desc_limit < 0x67 && (next_tss_desc.type & 8)) || |
@@ -2913,8 +2908,8 @@ static void string_addr_inc(struct x86_emulate_ctxt *ctxt, int reg, | |||
2913 | { | 2908 | { |
2914 | int df = (ctxt->eflags & EFLG_DF) ? -op->count : op->count; | 2909 | int df = (ctxt->eflags & EFLG_DF) ? -op->count : op->count; |
2915 | 2910 | ||
2916 | register_address_increment(ctxt, reg_rmw(ctxt, reg), df * op->bytes); | 2911 | register_address_increment(ctxt, reg, df * op->bytes); |
2917 | op->addr.mem.ea = register_address(ctxt, reg_read(ctxt, reg)); | 2912 | op->addr.mem.ea = register_address(ctxt, reg); |
2918 | } | 2913 | } |
2919 | 2914 | ||
2920 | static int em_das(struct x86_emulate_ctxt *ctxt) | 2915 | static int em_das(struct x86_emulate_ctxt *ctxt) |
@@ -3025,7 +3020,7 @@ static int em_call_far(struct x86_emulate_ctxt *ctxt) | |||
3025 | if (rc != X86EMUL_CONTINUE) | 3020 | if (rc != X86EMUL_CONTINUE) |
3026 | return X86EMUL_CONTINUE; | 3021 | return X86EMUL_CONTINUE; |
3027 | 3022 | ||
3028 | rc = assign_eip_far(ctxt, ctxt->src.val, new_desc.l); | 3023 | rc = assign_eip_far(ctxt, ctxt->src.val, &new_desc); |
3029 | if (rc != X86EMUL_CONTINUE) | 3024 | if (rc != X86EMUL_CONTINUE) |
3030 | goto fail; | 3025 | goto fail; |
3031 | 3026 | ||
@@ -3215,6 +3210,8 @@ static int em_mov_rm_sreg(struct x86_emulate_ctxt *ctxt) | |||
3215 | return emulate_ud(ctxt); | 3210 | return emulate_ud(ctxt); |
3216 | 3211 | ||
3217 | ctxt->dst.val = get_segment_selector(ctxt, ctxt->modrm_reg); | 3212 | ctxt->dst.val = get_segment_selector(ctxt, ctxt->modrm_reg); |
3213 | if (ctxt->dst.bytes == 4 && ctxt->dst.type == OP_MEM) | ||
3214 | ctxt->dst.bytes = 2; | ||
3218 | return X86EMUL_CONTINUE; | 3215 | return X86EMUL_CONTINUE; |
3219 | } | 3216 | } |
3220 | 3217 | ||
@@ -3317,7 +3314,7 @@ static int em_sidt(struct x86_emulate_ctxt *ctxt) | |||
3317 | return emulate_store_desc_ptr(ctxt, ctxt->ops->get_idt); | 3314 | return emulate_store_desc_ptr(ctxt, ctxt->ops->get_idt); |
3318 | } | 3315 | } |
3319 | 3316 | ||
3320 | static int em_lgdt(struct x86_emulate_ctxt *ctxt) | 3317 | static int em_lgdt_lidt(struct x86_emulate_ctxt *ctxt, bool lgdt) |
3321 | { | 3318 | { |
3322 | struct desc_ptr desc_ptr; | 3319 | struct desc_ptr desc_ptr; |
3323 | int rc; | 3320 | int rc; |
@@ -3329,12 +3326,23 @@ static int em_lgdt(struct x86_emulate_ctxt *ctxt) | |||
3329 | ctxt->op_bytes); | 3326 | ctxt->op_bytes); |
3330 | if (rc != X86EMUL_CONTINUE) | 3327 | if (rc != X86EMUL_CONTINUE) |
3331 | return rc; | 3328 | return rc; |
3332 | ctxt->ops->set_gdt(ctxt, &desc_ptr); | 3329 | if (ctxt->mode == X86EMUL_MODE_PROT64 && |
3330 | is_noncanonical_address(desc_ptr.address)) | ||
3331 | return emulate_gp(ctxt, 0); | ||
3332 | if (lgdt) | ||
3333 | ctxt->ops->set_gdt(ctxt, &desc_ptr); | ||
3334 | else | ||
3335 | ctxt->ops->set_idt(ctxt, &desc_ptr); | ||
3333 | /* Disable writeback. */ | 3336 | /* Disable writeback. */ |
3334 | ctxt->dst.type = OP_NONE; | 3337 | ctxt->dst.type = OP_NONE; |
3335 | return X86EMUL_CONTINUE; | 3338 | return X86EMUL_CONTINUE; |
3336 | } | 3339 | } |
3337 | 3340 | ||
3341 | static int em_lgdt(struct x86_emulate_ctxt *ctxt) | ||
3342 | { | ||
3343 | return em_lgdt_lidt(ctxt, true); | ||
3344 | } | ||
3345 | |||
3338 | static int em_vmmcall(struct x86_emulate_ctxt *ctxt) | 3346 | static int em_vmmcall(struct x86_emulate_ctxt *ctxt) |
3339 | { | 3347 | { |
3340 | int rc; | 3348 | int rc; |
@@ -3348,20 +3356,7 @@ static int em_vmmcall(struct x86_emulate_ctxt *ctxt) | |||
3348 | 3356 | ||
3349 | static int em_lidt(struct x86_emulate_ctxt *ctxt) | 3357 | static int em_lidt(struct x86_emulate_ctxt *ctxt) |
3350 | { | 3358 | { |
3351 | struct desc_ptr desc_ptr; | 3359 | return em_lgdt_lidt(ctxt, false); |
3352 | int rc; | ||
3353 | |||
3354 | if (ctxt->mode == X86EMUL_MODE_PROT64) | ||
3355 | ctxt->op_bytes = 8; | ||
3356 | rc = read_descriptor(ctxt, ctxt->src.addr.mem, | ||
3357 | &desc_ptr.size, &desc_ptr.address, | ||
3358 | ctxt->op_bytes); | ||
3359 | if (rc != X86EMUL_CONTINUE) | ||
3360 | return rc; | ||
3361 | ctxt->ops->set_idt(ctxt, &desc_ptr); | ||
3362 | /* Disable writeback. */ | ||
3363 | ctxt->dst.type = OP_NONE; | ||
3364 | return X86EMUL_CONTINUE; | ||
3365 | } | 3360 | } |
3366 | 3361 | ||
3367 | static int em_smsw(struct x86_emulate_ctxt *ctxt) | 3362 | static int em_smsw(struct x86_emulate_ctxt *ctxt) |
@@ -3384,7 +3379,7 @@ static int em_loop(struct x86_emulate_ctxt *ctxt) | |||
3384 | { | 3379 | { |
3385 | int rc = X86EMUL_CONTINUE; | 3380 | int rc = X86EMUL_CONTINUE; |
3386 | 3381 | ||
3387 | register_address_increment(ctxt, reg_rmw(ctxt, VCPU_REGS_RCX), -1); | 3382 | register_address_increment(ctxt, VCPU_REGS_RCX, -1); |
3388 | if ((address_mask(ctxt, reg_read(ctxt, VCPU_REGS_RCX)) != 0) && | 3383 | if ((address_mask(ctxt, reg_read(ctxt, VCPU_REGS_RCX)) != 0) && |
3389 | (ctxt->b == 0xe2 || test_cc(ctxt->b ^ 0x5, ctxt->eflags))) | 3384 | (ctxt->b == 0xe2 || test_cc(ctxt->b ^ 0x5, ctxt->eflags))) |
3390 | rc = jmp_rel(ctxt, ctxt->src.val); | 3385 | rc = jmp_rel(ctxt, ctxt->src.val); |
@@ -3554,7 +3549,7 @@ static int check_cr_write(struct x86_emulate_ctxt *ctxt) | |||
3554 | 3549 | ||
3555 | ctxt->ops->get_msr(ctxt, MSR_EFER, &efer); | 3550 | ctxt->ops->get_msr(ctxt, MSR_EFER, &efer); |
3556 | if (efer & EFER_LMA) | 3551 | if (efer & EFER_LMA) |
3557 | rsvd = CR3_L_MODE_RESERVED_BITS; | 3552 | rsvd = CR3_L_MODE_RESERVED_BITS & ~CR3_PCID_INVD; |
3558 | 3553 | ||
3559 | if (new_val & rsvd) | 3554 | if (new_val & rsvd) |
3560 | return emulate_gp(ctxt, 0); | 3555 | return emulate_gp(ctxt, 0); |
@@ -3596,8 +3591,15 @@ static int check_dr_read(struct x86_emulate_ctxt *ctxt) | |||
3596 | if ((cr4 & X86_CR4_DE) && (dr == 4 || dr == 5)) | 3591 | if ((cr4 & X86_CR4_DE) && (dr == 4 || dr == 5)) |
3597 | return emulate_ud(ctxt); | 3592 | return emulate_ud(ctxt); |
3598 | 3593 | ||
3599 | if (check_dr7_gd(ctxt)) | 3594 | if (check_dr7_gd(ctxt)) { |
3595 | ulong dr6; | ||
3596 | |||
3597 | ctxt->ops->get_dr(ctxt, 6, &dr6); | ||
3598 | dr6 &= ~15; | ||
3599 | dr6 |= DR6_BD | DR6_RTM; | ||
3600 | ctxt->ops->set_dr(ctxt, 6, dr6); | ||
3600 | return emulate_db(ctxt); | 3601 | return emulate_db(ctxt); |
3602 | } | ||
3601 | 3603 | ||
3602 | return X86EMUL_CONTINUE; | 3604 | return X86EMUL_CONTINUE; |
3603 | } | 3605 | } |
@@ -3684,6 +3686,7 @@ static int check_perm_out(struct x86_emulate_ctxt *ctxt) | |||
3684 | #define EXT(_f, _e) { .flags = ((_f) | RMExt), .u.group = (_e) } | 3686 | #define EXT(_f, _e) { .flags = ((_f) | RMExt), .u.group = (_e) } |
3685 | #define G(_f, _g) { .flags = ((_f) | Group | ModRM), .u.group = (_g) } | 3687 | #define G(_f, _g) { .flags = ((_f) | Group | ModRM), .u.group = (_g) } |
3686 | #define GD(_f, _g) { .flags = ((_f) | GroupDual | ModRM), .u.gdual = (_g) } | 3688 | #define GD(_f, _g) { .flags = ((_f) | GroupDual | ModRM), .u.gdual = (_g) } |
3689 | #define ID(_f, _i) { .flags = ((_f) | InstrDual | ModRM), .u.idual = (_i) } | ||
3687 | #define E(_f, _e) { .flags = ((_f) | Escape | ModRM), .u.esc = (_e) } | 3690 | #define E(_f, _e) { .flags = ((_f) | Escape | ModRM), .u.esc = (_e) } |
3688 | #define I(_f, _e) { .flags = (_f), .u.execute = (_e) } | 3691 | #define I(_f, _e) { .flags = (_f), .u.execute = (_e) } |
3689 | #define F(_f, _e) { .flags = (_f) | Fastop, .u.fastop = (_e) } | 3692 | #define F(_f, _e) { .flags = (_f) | Fastop, .u.fastop = (_e) } |
@@ -3780,11 +3783,11 @@ static const struct opcode group4[] = { | |||
3780 | static const struct opcode group5[] = { | 3783 | static const struct opcode group5[] = { |
3781 | F(DstMem | SrcNone | Lock, em_inc), | 3784 | F(DstMem | SrcNone | Lock, em_inc), |
3782 | F(DstMem | SrcNone | Lock, em_dec), | 3785 | F(DstMem | SrcNone | Lock, em_dec), |
3783 | I(SrcMem | Stack, em_grp45), | 3786 | I(SrcMem | NearBranch, em_call_near_abs), |
3784 | I(SrcMemFAddr | ImplicitOps | Stack, em_call_far), | 3787 | I(SrcMemFAddr | ImplicitOps | Stack, em_call_far), |
3785 | I(SrcMem | Stack, em_grp45), | 3788 | I(SrcMem | NearBranch, em_jmp_abs), |
3786 | I(SrcMemFAddr | ImplicitOps, em_grp45), | 3789 | I(SrcMemFAddr | ImplicitOps, em_jmp_far), |
3787 | I(SrcMem | Stack, em_grp45), D(Undefined), | 3790 | I(SrcMem | Stack, em_push), D(Undefined), |
3788 | }; | 3791 | }; |
3789 | 3792 | ||
3790 | static const struct opcode group6[] = { | 3793 | static const struct opcode group6[] = { |
@@ -3845,8 +3848,12 @@ static const struct gprefix pfx_0f_6f_0f_7f = { | |||
3845 | I(Mmx, em_mov), I(Sse | Aligned, em_mov), N, I(Sse | Unaligned, em_mov), | 3848 | I(Mmx, em_mov), I(Sse | Aligned, em_mov), N, I(Sse | Unaligned, em_mov), |
3846 | }; | 3849 | }; |
3847 | 3850 | ||
3851 | static const struct instr_dual instr_dual_0f_2b = { | ||
3852 | I(0, em_mov), N | ||
3853 | }; | ||
3854 | |||
3848 | static const struct gprefix pfx_0f_2b = { | 3855 | static const struct gprefix pfx_0f_2b = { |
3849 | I(0, em_mov), I(0, em_mov), N, N, | 3856 | ID(0, &instr_dual_0f_2b), ID(0, &instr_dual_0f_2b), N, N, |
3850 | }; | 3857 | }; |
3851 | 3858 | ||
3852 | static const struct gprefix pfx_0f_28_0f_29 = { | 3859 | static const struct gprefix pfx_0f_28_0f_29 = { |
@@ -3920,6 +3927,10 @@ static const struct escape escape_dd = { { | |||
3920 | N, N, N, N, N, N, N, N, | 3927 | N, N, N, N, N, N, N, N, |
3921 | } }; | 3928 | } }; |
3922 | 3929 | ||
3930 | static const struct instr_dual instr_dual_0f_c3 = { | ||
3931 | I(DstMem | SrcReg | ModRM | No16 | Mov, em_mov), N | ||
3932 | }; | ||
3933 | |||
3923 | static const struct opcode opcode_table[256] = { | 3934 | static const struct opcode opcode_table[256] = { |
3924 | /* 0x00 - 0x07 */ | 3935 | /* 0x00 - 0x07 */ |
3925 | F6ALU(Lock, em_add), | 3936 | F6ALU(Lock, em_add), |
@@ -3964,7 +3975,7 @@ static const struct opcode opcode_table[256] = { | |||
3964 | I2bvIP(DstDI | SrcDX | Mov | String | Unaligned, em_in, ins, check_perm_in), /* insb, insw/insd */ | 3975 | I2bvIP(DstDI | SrcDX | Mov | String | Unaligned, em_in, ins, check_perm_in), /* insb, insw/insd */ |
3965 | I2bvIP(SrcSI | DstDX | String, em_out, outs, check_perm_out), /* outsb, outsw/outsd */ | 3976 | I2bvIP(SrcSI | DstDX | String, em_out, outs, check_perm_out), /* outsb, outsw/outsd */ |
3966 | /* 0x70 - 0x7F */ | 3977 | /* 0x70 - 0x7F */ |
3967 | X16(D(SrcImmByte)), | 3978 | X16(D(SrcImmByte | NearBranch)), |
3968 | /* 0x80 - 0x87 */ | 3979 | /* 0x80 - 0x87 */ |
3969 | G(ByteOp | DstMem | SrcImm, group1), | 3980 | G(ByteOp | DstMem | SrcImm, group1), |
3970 | G(DstMem | SrcImm, group1), | 3981 | G(DstMem | SrcImm, group1), |
@@ -3991,20 +4002,20 @@ static const struct opcode opcode_table[256] = { | |||
3991 | I2bv(DstAcc | SrcMem | Mov | MemAbs, em_mov), | 4002 | I2bv(DstAcc | SrcMem | Mov | MemAbs, em_mov), |
3992 | I2bv(DstMem | SrcAcc | Mov | MemAbs | PageTable, em_mov), | 4003 | I2bv(DstMem | SrcAcc | Mov | MemAbs | PageTable, em_mov), |
3993 | I2bv(SrcSI | DstDI | Mov | String, em_mov), | 4004 | I2bv(SrcSI | DstDI | Mov | String, em_mov), |
3994 | F2bv(SrcSI | DstDI | String | NoWrite, em_cmp), | 4005 | F2bv(SrcSI | DstDI | String | NoWrite, em_cmp_r), |
3995 | /* 0xA8 - 0xAF */ | 4006 | /* 0xA8 - 0xAF */ |
3996 | F2bv(DstAcc | SrcImm | NoWrite, em_test), | 4007 | F2bv(DstAcc | SrcImm | NoWrite, em_test), |
3997 | I2bv(SrcAcc | DstDI | Mov | String, em_mov), | 4008 | I2bv(SrcAcc | DstDI | Mov | String, em_mov), |
3998 | I2bv(SrcSI | DstAcc | Mov | String, em_mov), | 4009 | I2bv(SrcSI | DstAcc | Mov | String, em_mov), |
3999 | F2bv(SrcAcc | DstDI | String | NoWrite, em_cmp), | 4010 | F2bv(SrcAcc | DstDI | String | NoWrite, em_cmp_r), |
4000 | /* 0xB0 - 0xB7 */ | 4011 | /* 0xB0 - 0xB7 */ |
4001 | X8(I(ByteOp | DstReg | SrcImm | Mov, em_mov)), | 4012 | X8(I(ByteOp | DstReg | SrcImm | Mov, em_mov)), |
4002 | /* 0xB8 - 0xBF */ | 4013 | /* 0xB8 - 0xBF */ |
4003 | X8(I(DstReg | SrcImm64 | Mov, em_mov)), | 4014 | X8(I(DstReg | SrcImm64 | Mov, em_mov)), |
4004 | /* 0xC0 - 0xC7 */ | 4015 | /* 0xC0 - 0xC7 */ |
4005 | G(ByteOp | Src2ImmByte, group2), G(Src2ImmByte, group2), | 4016 | G(ByteOp | Src2ImmByte, group2), G(Src2ImmByte, group2), |
4006 | I(ImplicitOps | Stack | SrcImmU16, em_ret_near_imm), | 4017 | I(ImplicitOps | NearBranch | SrcImmU16, em_ret_near_imm), |
4007 | I(ImplicitOps | Stack, em_ret), | 4018 | I(ImplicitOps | NearBranch, em_ret), |
4008 | I(DstReg | SrcMemFAddr | ModRM | No64 | Src2ES, em_lseg), | 4019 | I(DstReg | SrcMemFAddr | ModRM | No64 | Src2ES, em_lseg), |
4009 | I(DstReg | SrcMemFAddr | ModRM | No64 | Src2DS, em_lseg), | 4020 | I(DstReg | SrcMemFAddr | ModRM | No64 | Src2DS, em_lseg), |
4010 | G(ByteOp, group11), G(0, group11), | 4021 | G(ByteOp, group11), G(0, group11), |
@@ -4024,13 +4035,14 @@ static const struct opcode opcode_table[256] = { | |||
4024 | /* 0xD8 - 0xDF */ | 4035 | /* 0xD8 - 0xDF */ |
4025 | N, E(0, &escape_d9), N, E(0, &escape_db), N, E(0, &escape_dd), N, N, | 4036 | N, E(0, &escape_d9), N, E(0, &escape_db), N, E(0, &escape_dd), N, N, |
4026 | /* 0xE0 - 0xE7 */ | 4037 | /* 0xE0 - 0xE7 */ |
4027 | X3(I(SrcImmByte, em_loop)), | 4038 | X3(I(SrcImmByte | NearBranch, em_loop)), |
4028 | I(SrcImmByte, em_jcxz), | 4039 | I(SrcImmByte | NearBranch, em_jcxz), |
4029 | I2bvIP(SrcImmUByte | DstAcc, em_in, in, check_perm_in), | 4040 | I2bvIP(SrcImmUByte | DstAcc, em_in, in, check_perm_in), |
4030 | I2bvIP(SrcAcc | DstImmUByte, em_out, out, check_perm_out), | 4041 | I2bvIP(SrcAcc | DstImmUByte, em_out, out, check_perm_out), |
4031 | /* 0xE8 - 0xEF */ | 4042 | /* 0xE8 - 0xEF */ |
4032 | I(SrcImm | Stack, em_call), D(SrcImm | ImplicitOps), | 4043 | I(SrcImm | NearBranch, em_call), D(SrcImm | ImplicitOps | NearBranch), |
4033 | I(SrcImmFAddr | No64, em_jmp_far), D(SrcImmByte | ImplicitOps), | 4044 | I(SrcImmFAddr | No64, em_jmp_far), |
4045 | D(SrcImmByte | ImplicitOps | NearBranch), | ||
4034 | I2bvIP(SrcDX | DstAcc, em_in, in, check_perm_in), | 4046 | I2bvIP(SrcDX | DstAcc, em_in, in, check_perm_in), |
4035 | I2bvIP(SrcAcc | DstDX, em_out, out, check_perm_out), | 4047 | I2bvIP(SrcAcc | DstDX, em_out, out, check_perm_out), |
4036 | /* 0xF0 - 0xF7 */ | 4048 | /* 0xF0 - 0xF7 */ |
@@ -4090,7 +4102,7 @@ static const struct opcode twobyte_table[256] = { | |||
4090 | N, N, N, N, | 4102 | N, N, N, N, |
4091 | N, N, N, GP(SrcReg | DstMem | ModRM | Mov, &pfx_0f_6f_0f_7f), | 4103 | N, N, N, GP(SrcReg | DstMem | ModRM | Mov, &pfx_0f_6f_0f_7f), |
4092 | /* 0x80 - 0x8F */ | 4104 | /* 0x80 - 0x8F */ |
4093 | X16(D(SrcImm)), | 4105 | X16(D(SrcImm | NearBranch)), |
4094 | /* 0x90 - 0x9F */ | 4106 | /* 0x90 - 0x9F */ |
4095 | X16(D(ByteOp | DstMem | SrcNone | ModRM| Mov)), | 4107 | X16(D(ByteOp | DstMem | SrcNone | ModRM| Mov)), |
4096 | /* 0xA0 - 0xA7 */ | 4108 | /* 0xA0 - 0xA7 */ |
@@ -4121,7 +4133,7 @@ static const struct opcode twobyte_table[256] = { | |||
4121 | D(DstReg | SrcMem8 | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), | 4133 | D(DstReg | SrcMem8 | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), |
4122 | /* 0xC0 - 0xC7 */ | 4134 | /* 0xC0 - 0xC7 */ |
4123 | F2bv(DstMem | SrcReg | ModRM | SrcWrite | Lock, em_xadd), | 4135 | F2bv(DstMem | SrcReg | ModRM | SrcWrite | Lock, em_xadd), |
4124 | N, D(DstMem | SrcReg | ModRM | Mov), | 4136 | N, ID(0, &instr_dual_0f_c3), |
4125 | N, N, N, GD(0, &group9), | 4137 | N, N, N, GD(0, &group9), |
4126 | /* 0xC8 - 0xCF */ | 4138 | /* 0xC8 - 0xCF */ |
4127 | X8(I(DstReg, em_bswap)), | 4139 | X8(I(DstReg, em_bswap)), |
@@ -4134,12 +4146,20 @@ static const struct opcode twobyte_table[256] = { | |||
4134 | N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N | 4146 | N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N |
4135 | }; | 4147 | }; |
4136 | 4148 | ||
4149 | static const struct instr_dual instr_dual_0f_38_f0 = { | ||
4150 | I(DstReg | SrcMem | Mov, em_movbe), N | ||
4151 | }; | ||
4152 | |||
4153 | static const struct instr_dual instr_dual_0f_38_f1 = { | ||
4154 | I(DstMem | SrcReg | Mov, em_movbe), N | ||
4155 | }; | ||
4156 | |||
4137 | static const struct gprefix three_byte_0f_38_f0 = { | 4157 | static const struct gprefix three_byte_0f_38_f0 = { |
4138 | I(DstReg | SrcMem | Mov, em_movbe), N, N, N | 4158 | ID(0, &instr_dual_0f_38_f0), N, N, N |
4139 | }; | 4159 | }; |
4140 | 4160 | ||
4141 | static const struct gprefix three_byte_0f_38_f1 = { | 4161 | static const struct gprefix three_byte_0f_38_f1 = { |
4142 | I(DstMem | SrcReg | Mov, em_movbe), N, N, N | 4162 | ID(0, &instr_dual_0f_38_f1), N, N, N |
4143 | }; | 4163 | }; |
4144 | 4164 | ||
4145 | /* | 4165 | /* |
@@ -4152,8 +4172,8 @@ static const struct opcode opcode_map_0f_38[256] = { | |||
4152 | /* 0x80 - 0xef */ | 4172 | /* 0x80 - 0xef */ |
4153 | X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), | 4173 | X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), X16(N), |
4154 | /* 0xf0 - 0xf1 */ | 4174 | /* 0xf0 - 0xf1 */ |
4155 | GP(EmulateOnUD | ModRM | Prefix, &three_byte_0f_38_f0), | 4175 | GP(EmulateOnUD | ModRM, &three_byte_0f_38_f0), |
4156 | GP(EmulateOnUD | ModRM | Prefix, &three_byte_0f_38_f1), | 4176 | GP(EmulateOnUD | ModRM, &three_byte_0f_38_f1), |
4157 | /* 0xf2 - 0xff */ | 4177 | /* 0xf2 - 0xff */ |
4158 | N, N, X4(N), X8(N) | 4178 | N, N, X4(N), X8(N) |
4159 | }; | 4179 | }; |
@@ -4275,7 +4295,7 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op, | |||
4275 | op->type = OP_MEM; | 4295 | op->type = OP_MEM; |
4276 | op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; | 4296 | op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; |
4277 | op->addr.mem.ea = | 4297 | op->addr.mem.ea = |
4278 | register_address(ctxt, reg_read(ctxt, VCPU_REGS_RDI)); | 4298 | register_address(ctxt, VCPU_REGS_RDI); |
4279 | op->addr.mem.seg = VCPU_SREG_ES; | 4299 | op->addr.mem.seg = VCPU_SREG_ES; |
4280 | op->val = 0; | 4300 | op->val = 0; |
4281 | op->count = 1; | 4301 | op->count = 1; |
@@ -4329,7 +4349,7 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op, | |||
4329 | op->type = OP_MEM; | 4349 | op->type = OP_MEM; |
4330 | op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; | 4350 | op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; |
4331 | op->addr.mem.ea = | 4351 | op->addr.mem.ea = |
4332 | register_address(ctxt, reg_read(ctxt, VCPU_REGS_RSI)); | 4352 | register_address(ctxt, VCPU_REGS_RSI); |
4333 | op->addr.mem.seg = ctxt->seg_override; | 4353 | op->addr.mem.seg = ctxt->seg_override; |
4334 | op->val = 0; | 4354 | op->val = 0; |
4335 | op->count = 1; | 4355 | op->count = 1; |
@@ -4338,7 +4358,7 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op, | |||
4338 | op->type = OP_MEM; | 4358 | op->type = OP_MEM; |
4339 | op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; | 4359 | op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; |
4340 | op->addr.mem.ea = | 4360 | op->addr.mem.ea = |
4341 | register_address(ctxt, | 4361 | address_mask(ctxt, |
4342 | reg_read(ctxt, VCPU_REGS_RBX) + | 4362 | reg_read(ctxt, VCPU_REGS_RBX) + |
4343 | (reg_read(ctxt, VCPU_REGS_RAX) & 0xff)); | 4363 | (reg_read(ctxt, VCPU_REGS_RAX) & 0xff)); |
4344 | op->addr.mem.seg = ctxt->seg_override; | 4364 | op->addr.mem.seg = ctxt->seg_override; |
@@ -4510,8 +4530,7 @@ done_prefixes: | |||
4510 | 4530 | ||
4511 | /* vex-prefix instructions are not implemented */ | 4531 | /* vex-prefix instructions are not implemented */ |
4512 | if (ctxt->opcode_len == 1 && (ctxt->b == 0xc5 || ctxt->b == 0xc4) && | 4532 | if (ctxt->opcode_len == 1 && (ctxt->b == 0xc5 || ctxt->b == 0xc4) && |
4513 | (mode == X86EMUL_MODE_PROT64 || | 4533 | (mode == X86EMUL_MODE_PROT64 || (ctxt->modrm & 0xc0) == 0xc0)) { |
4514 | (mode >= X86EMUL_MODE_PROT16 && (ctxt->modrm & 0x80)))) { | ||
4515 | ctxt->d = NotImpl; | 4534 | ctxt->d = NotImpl; |
4516 | } | 4535 | } |
4517 | 4536 | ||
@@ -4549,6 +4568,12 @@ done_prefixes: | |||
4549 | else | 4568 | else |
4550 | opcode = opcode.u.esc->op[(ctxt->modrm >> 3) & 7]; | 4569 | opcode = opcode.u.esc->op[(ctxt->modrm >> 3) & 7]; |
4551 | break; | 4570 | break; |
4571 | case InstrDual: | ||
4572 | if ((ctxt->modrm >> 6) == 3) | ||
4573 | opcode = opcode.u.idual->mod3; | ||
4574 | else | ||
4575 | opcode = opcode.u.idual->mod012; | ||
4576 | break; | ||
4552 | default: | 4577 | default: |
4553 | return EMULATION_FAILED; | 4578 | return EMULATION_FAILED; |
4554 | } | 4579 | } |
@@ -4567,7 +4592,8 @@ done_prefixes: | |||
4567 | return EMULATION_FAILED; | 4592 | return EMULATION_FAILED; |
4568 | 4593 | ||
4569 | if (unlikely(ctxt->d & | 4594 | if (unlikely(ctxt->d & |
4570 | (NotImpl|Stack|Op3264|Sse|Mmx|Intercept|CheckPerm))) { | 4595 | (NotImpl|Stack|Op3264|Sse|Mmx|Intercept|CheckPerm|NearBranch| |
4596 | No16))) { | ||
4571 | /* | 4597 | /* |
4572 | * These are copied unconditionally here, and checked unconditionally | 4598 | * These are copied unconditionally here, and checked unconditionally |
4573 | * in x86_emulate_insn. | 4599 | * in x86_emulate_insn. |
@@ -4578,8 +4604,12 @@ done_prefixes: | |||
4578 | if (ctxt->d & NotImpl) | 4604 | if (ctxt->d & NotImpl) |
4579 | return EMULATION_FAILED; | 4605 | return EMULATION_FAILED; |
4580 | 4606 | ||
4581 | if (mode == X86EMUL_MODE_PROT64 && (ctxt->d & Stack)) | 4607 | if (mode == X86EMUL_MODE_PROT64) { |
4582 | ctxt->op_bytes = 8; | 4608 | if (ctxt->op_bytes == 4 && (ctxt->d & Stack)) |
4609 | ctxt->op_bytes = 8; | ||
4610 | else if (ctxt->d & NearBranch) | ||
4611 | ctxt->op_bytes = 8; | ||
4612 | } | ||
4583 | 4613 | ||
4584 | if (ctxt->d & Op3264) { | 4614 | if (ctxt->d & Op3264) { |
4585 | if (mode == X86EMUL_MODE_PROT64) | 4615 | if (mode == X86EMUL_MODE_PROT64) |
@@ -4588,6 +4618,9 @@ done_prefixes: | |||
4588 | ctxt->op_bytes = 4; | 4618 | ctxt->op_bytes = 4; |
4589 | } | 4619 | } |
4590 | 4620 | ||
4621 | if ((ctxt->d & No16) && ctxt->op_bytes == 2) | ||
4622 | ctxt->op_bytes = 4; | ||
4623 | |||
4591 | if (ctxt->d & Sse) | 4624 | if (ctxt->d & Sse) |
4592 | ctxt->op_bytes = 16; | 4625 | ctxt->op_bytes = 16; |
4593 | else if (ctxt->d & Mmx) | 4626 | else if (ctxt->d & Mmx) |
@@ -4631,7 +4664,8 @@ done_prefixes: | |||
4631 | rc = decode_operand(ctxt, &ctxt->dst, (ctxt->d >> DstShift) & OpMask); | 4664 | rc = decode_operand(ctxt, &ctxt->dst, (ctxt->d >> DstShift) & OpMask); |
4632 | 4665 | ||
4633 | if (ctxt->rip_relative) | 4666 | if (ctxt->rip_relative) |
4634 | ctxt->memopp->addr.mem.ea += ctxt->_eip; | 4667 | ctxt->memopp->addr.mem.ea = address_mask(ctxt, |
4668 | ctxt->memopp->addr.mem.ea + ctxt->_eip); | ||
4635 | 4669 | ||
4636 | done: | 4670 | done: |
4637 | return (rc != X86EMUL_CONTINUE) ? EMULATION_FAILED : EMULATION_OK; | 4671 | return (rc != X86EMUL_CONTINUE) ? EMULATION_FAILED : EMULATION_OK; |
@@ -4775,6 +4809,12 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) | |||
4775 | goto done; | 4809 | goto done; |
4776 | } | 4810 | } |
4777 | 4811 | ||
4812 | /* Instruction can only be executed in protected mode */ | ||
4813 | if ((ctxt->d & Prot) && ctxt->mode < X86EMUL_MODE_PROT16) { | ||
4814 | rc = emulate_ud(ctxt); | ||
4815 | goto done; | ||
4816 | } | ||
4817 | |||
4778 | /* Privileged instruction can be executed only in CPL=0 */ | 4818 | /* Privileged instruction can be executed only in CPL=0 */ |
4779 | if ((ctxt->d & Priv) && ops->cpl(ctxt)) { | 4819 | if ((ctxt->d & Priv) && ops->cpl(ctxt)) { |
4780 | if (ctxt->d & PrivUD) | 4820 | if (ctxt->d & PrivUD) |
@@ -4784,12 +4824,6 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) | |||
4784 | goto done; | 4824 | goto done; |
4785 | } | 4825 | } |
4786 | 4826 | ||
4787 | /* Instruction can only be executed in protected mode */ | ||
4788 | if ((ctxt->d & Prot) && ctxt->mode < X86EMUL_MODE_PROT16) { | ||
4789 | rc = emulate_ud(ctxt); | ||
4790 | goto done; | ||
4791 | } | ||
4792 | |||
4793 | /* Do instruction specific permission checks */ | 4827 | /* Do instruction specific permission checks */ |
4794 | if (ctxt->d & CheckPerm) { | 4828 | if (ctxt->d & CheckPerm) { |
4795 | rc = ctxt->check_perm(ctxt); | 4829 | rc = ctxt->check_perm(ctxt); |
@@ -4974,8 +5008,7 @@ writeback: | |||
4974 | count = ctxt->src.count; | 5008 | count = ctxt->src.count; |
4975 | else | 5009 | else |
4976 | count = ctxt->dst.count; | 5010 | count = ctxt->dst.count; |
4977 | register_address_increment(ctxt, reg_rmw(ctxt, VCPU_REGS_RCX), | 5011 | register_address_increment(ctxt, VCPU_REGS_RCX, -count); |
4978 | -count); | ||
4979 | 5012 | ||
4980 | if (!string_insn_completed(ctxt)) { | 5013 | if (!string_insn_completed(ctxt)) { |
4981 | /* | 5014 | /* |
@@ -5053,11 +5086,6 @@ twobyte_insn: | |||
5053 | ctxt->dst.val = (ctxt->src.bytes == 1) ? (s8) ctxt->src.val : | 5086 | ctxt->dst.val = (ctxt->src.bytes == 1) ? (s8) ctxt->src.val : |
5054 | (s16) ctxt->src.val; | 5087 | (s16) ctxt->src.val; |
5055 | break; | 5088 | break; |
5056 | case 0xc3: /* movnti */ | ||
5057 | ctxt->dst.bytes = ctxt->op_bytes; | ||
5058 | ctxt->dst.val = (ctxt->op_bytes == 8) ? (u64) ctxt->src.val : | ||
5059 | (u32) ctxt->src.val; | ||
5060 | break; | ||
5061 | default: | 5089 | default: |
5062 | goto cannot_emulate; | 5090 | goto cannot_emulate; |
5063 | } | 5091 | } |
diff --git a/virt/kvm/ioapic.c b/arch/x86/kvm/ioapic.c index 0ba4057d271b..b1947e0f3e10 100644 --- a/virt/kvm/ioapic.c +++ b/arch/x86/kvm/ioapic.c | |||
@@ -270,7 +270,6 @@ void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap, | |||
270 | spin_unlock(&ioapic->lock); | 270 | spin_unlock(&ioapic->lock); |
271 | } | 271 | } |
272 | 272 | ||
273 | #ifdef CONFIG_X86 | ||
274 | void kvm_vcpu_request_scan_ioapic(struct kvm *kvm) | 273 | void kvm_vcpu_request_scan_ioapic(struct kvm *kvm) |
275 | { | 274 | { |
276 | struct kvm_ioapic *ioapic = kvm->arch.vioapic; | 275 | struct kvm_ioapic *ioapic = kvm->arch.vioapic; |
@@ -279,12 +278,6 @@ void kvm_vcpu_request_scan_ioapic(struct kvm *kvm) | |||
279 | return; | 278 | return; |
280 | kvm_make_scan_ioapic_request(kvm); | 279 | kvm_make_scan_ioapic_request(kvm); |
281 | } | 280 | } |
282 | #else | ||
283 | void kvm_vcpu_request_scan_ioapic(struct kvm *kvm) | ||
284 | { | ||
285 | return; | ||
286 | } | ||
287 | #endif | ||
288 | 281 | ||
289 | static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) | 282 | static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) |
290 | { | 283 | { |
@@ -586,11 +579,6 @@ static int ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len, | |||
586 | case IOAPIC_REG_WINDOW: | 579 | case IOAPIC_REG_WINDOW: |
587 | ioapic_write_indirect(ioapic, data); | 580 | ioapic_write_indirect(ioapic, data); |
588 | break; | 581 | break; |
589 | #ifdef CONFIG_IA64 | ||
590 | case IOAPIC_REG_EOI: | ||
591 | __kvm_ioapic_update_eoi(NULL, ioapic, data, IOAPIC_LEVEL_TRIG); | ||
592 | break; | ||
593 | #endif | ||
594 | 582 | ||
595 | default: | 583 | default: |
596 | break; | 584 | break; |
diff --git a/virt/kvm/ioapic.h b/arch/x86/kvm/ioapic.h index e23b70634f1e..3c9195535ffc 100644 --- a/virt/kvm/ioapic.h +++ b/arch/x86/kvm/ioapic.h | |||
@@ -19,7 +19,6 @@ struct kvm_vcpu; | |||
19 | /* Direct registers. */ | 19 | /* Direct registers. */ |
20 | #define IOAPIC_REG_SELECT 0x00 | 20 | #define IOAPIC_REG_SELECT 0x00 |
21 | #define IOAPIC_REG_WINDOW 0x10 | 21 | #define IOAPIC_REG_WINDOW 0x10 |
22 | #define IOAPIC_REG_EOI 0x40 /* IA64 IOSAPIC only */ | ||
23 | 22 | ||
24 | /* Indirect registers. */ | 23 | /* Indirect registers. */ |
25 | #define IOAPIC_REG_APIC_ID 0x00 /* x86 IOAPIC only */ | 24 | #define IOAPIC_REG_APIC_ID 0x00 /* x86 IOAPIC only */ |
@@ -45,6 +44,23 @@ struct rtc_status { | |||
45 | DECLARE_BITMAP(dest_map, KVM_MAX_VCPUS); | 44 | DECLARE_BITMAP(dest_map, KVM_MAX_VCPUS); |
46 | }; | 45 | }; |
47 | 46 | ||
47 | union kvm_ioapic_redirect_entry { | ||
48 | u64 bits; | ||
49 | struct { | ||
50 | u8 vector; | ||
51 | u8 delivery_mode:3; | ||
52 | u8 dest_mode:1; | ||
53 | u8 delivery_status:1; | ||
54 | u8 polarity:1; | ||
55 | u8 remote_irr:1; | ||
56 | u8 trig_mode:1; | ||
57 | u8 mask:1; | ||
58 | u8 reserve:7; | ||
59 | u8 reserved[4]; | ||
60 | u8 dest_id; | ||
61 | } fields; | ||
62 | }; | ||
63 | |||
48 | struct kvm_ioapic { | 64 | struct kvm_ioapic { |
49 | u64 base_address; | 65 | u64 base_address; |
50 | u32 ioregsel; | 66 | u32 ioregsel; |
@@ -83,7 +99,7 @@ static inline struct kvm_ioapic *ioapic_irqchip(struct kvm *kvm) | |||
83 | 99 | ||
84 | void kvm_rtc_eoi_tracking_restore_one(struct kvm_vcpu *vcpu); | 100 | void kvm_rtc_eoi_tracking_restore_one(struct kvm_vcpu *vcpu); |
85 | int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, | 101 | int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, |
86 | int short_hand, int dest, int dest_mode); | 102 | int short_hand, unsigned int dest, int dest_mode); |
87 | int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2); | 103 | int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2); |
88 | void kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, int vector, | 104 | void kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, int vector, |
89 | int trigger_mode); | 105 | int trigger_mode); |
@@ -97,7 +113,6 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, | |||
97 | struct kvm_lapic_irq *irq, unsigned long *dest_map); | 113 | struct kvm_lapic_irq *irq, unsigned long *dest_map); |
98 | int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state); | 114 | int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state); |
99 | int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state); | 115 | int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state); |
100 | void kvm_vcpu_request_scan_ioapic(struct kvm *kvm); | ||
101 | void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap, | 116 | void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap, |
102 | u32 *tmr); | 117 | u32 *tmr); |
103 | 118 | ||
diff --git a/virt/kvm/iommu.c b/arch/x86/kvm/iommu.c index c1e6ae989a43..17b73eeac8a4 100644 --- a/virt/kvm/iommu.c +++ b/arch/x86/kvm/iommu.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/dmar.h> | 31 | #include <linux/dmar.h> |
32 | #include <linux/iommu.h> | 32 | #include <linux/iommu.h> |
33 | #include <linux/intel-iommu.h> | 33 | #include <linux/intel-iommu.h> |
34 | #include "assigned-dev.h" | ||
34 | 35 | ||
35 | static bool allow_unsafe_assigned_interrupts; | 36 | static bool allow_unsafe_assigned_interrupts; |
36 | module_param_named(allow_unsafe_assigned_interrupts, | 37 | module_param_named(allow_unsafe_assigned_interrupts, |
@@ -169,10 +170,8 @@ static int kvm_iommu_map_memslots(struct kvm *kvm) | |||
169 | return r; | 170 | return r; |
170 | } | 171 | } |
171 | 172 | ||
172 | int kvm_assign_device(struct kvm *kvm, | 173 | int kvm_assign_device(struct kvm *kvm, struct pci_dev *pdev) |
173 | struct kvm_assigned_dev_kernel *assigned_dev) | ||
174 | { | 174 | { |
175 | struct pci_dev *pdev = NULL; | ||
176 | struct iommu_domain *domain = kvm->arch.iommu_domain; | 175 | struct iommu_domain *domain = kvm->arch.iommu_domain; |
177 | int r; | 176 | int r; |
178 | bool noncoherent; | 177 | bool noncoherent; |
@@ -181,7 +180,6 @@ int kvm_assign_device(struct kvm *kvm, | |||
181 | if (!domain) | 180 | if (!domain) |
182 | return 0; | 181 | return 0; |
183 | 182 | ||
184 | pdev = assigned_dev->dev; | ||
185 | if (pdev == NULL) | 183 | if (pdev == NULL) |
186 | return -ENODEV; | 184 | return -ENODEV; |
187 | 185 | ||
@@ -212,17 +210,14 @@ out_unmap: | |||
212 | return r; | 210 | return r; |
213 | } | 211 | } |
214 | 212 | ||
215 | int kvm_deassign_device(struct kvm *kvm, | 213 | int kvm_deassign_device(struct kvm *kvm, struct pci_dev *pdev) |
216 | struct kvm_assigned_dev_kernel *assigned_dev) | ||
217 | { | 214 | { |
218 | struct iommu_domain *domain = kvm->arch.iommu_domain; | 215 | struct iommu_domain *domain = kvm->arch.iommu_domain; |
219 | struct pci_dev *pdev = NULL; | ||
220 | 216 | ||
221 | /* check if iommu exists and in use */ | 217 | /* check if iommu exists and in use */ |
222 | if (!domain) | 218 | if (!domain) |
223 | return 0; | 219 | return 0; |
224 | 220 | ||
225 | pdev = assigned_dev->dev; | ||
226 | if (pdev == NULL) | 221 | if (pdev == NULL) |
227 | return -ENODEV; | 222 | return -ENODEV; |
228 | 223 | ||
diff --git a/virt/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c index 963b8995a9e8..72298b3ac025 100644 --- a/virt/kvm/irq_comm.c +++ b/arch/x86/kvm/irq_comm.c | |||
@@ -26,9 +26,6 @@ | |||
26 | #include <trace/events/kvm.h> | 26 | #include <trace/events/kvm.h> |
27 | 27 | ||
28 | #include <asm/msidef.h> | 28 | #include <asm/msidef.h> |
29 | #ifdef CONFIG_IA64 | ||
30 | #include <asm/iosapic.h> | ||
31 | #endif | ||
32 | 29 | ||
33 | #include "irq.h" | 30 | #include "irq.h" |
34 | 31 | ||
@@ -38,12 +35,8 @@ static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e, | |||
38 | struct kvm *kvm, int irq_source_id, int level, | 35 | struct kvm *kvm, int irq_source_id, int level, |
39 | bool line_status) | 36 | bool line_status) |
40 | { | 37 | { |
41 | #ifdef CONFIG_X86 | ||
42 | struct kvm_pic *pic = pic_irqchip(kvm); | 38 | struct kvm_pic *pic = pic_irqchip(kvm); |
43 | return kvm_pic_set_irq(pic, e->irqchip.pin, irq_source_id, level); | 39 | return kvm_pic_set_irq(pic, e->irqchip.pin, irq_source_id, level); |
44 | #else | ||
45 | return -1; | ||
46 | #endif | ||
47 | } | 40 | } |
48 | 41 | ||
49 | static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e, | 42 | static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e, |
@@ -57,12 +50,7 @@ static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e, | |||
57 | 50 | ||
58 | inline static bool kvm_is_dm_lowest_prio(struct kvm_lapic_irq *irq) | 51 | inline static bool kvm_is_dm_lowest_prio(struct kvm_lapic_irq *irq) |
59 | { | 52 | { |
60 | #ifdef CONFIG_IA64 | ||
61 | return irq->delivery_mode == | ||
62 | (IOSAPIC_LOWEST_PRIORITY << IOSAPIC_DELIVERY_SHIFT); | ||
63 | #else | ||
64 | return irq->delivery_mode == APIC_DM_LOWEST; | 53 | return irq->delivery_mode == APIC_DM_LOWEST; |
65 | #endif | ||
66 | } | 54 | } |
67 | 55 | ||
68 | int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, | 56 | int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, |
@@ -202,9 +190,7 @@ int kvm_request_irq_source_id(struct kvm *kvm) | |||
202 | } | 190 | } |
203 | 191 | ||
204 | ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID); | 192 | ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID); |
205 | #ifdef CONFIG_X86 | ||
206 | ASSERT(irq_source_id != KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID); | 193 | ASSERT(irq_source_id != KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID); |
207 | #endif | ||
208 | set_bit(irq_source_id, bitmap); | 194 | set_bit(irq_source_id, bitmap); |
209 | unlock: | 195 | unlock: |
210 | mutex_unlock(&kvm->irq_lock); | 196 | mutex_unlock(&kvm->irq_lock); |
@@ -215,9 +201,7 @@ unlock: | |||
215 | void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id) | 201 | void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id) |
216 | { | 202 | { |
217 | ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID); | 203 | ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID); |
218 | #ifdef CONFIG_X86 | ||
219 | ASSERT(irq_source_id != KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID); | 204 | ASSERT(irq_source_id != KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID); |
220 | #endif | ||
221 | 205 | ||
222 | mutex_lock(&kvm->irq_lock); | 206 | mutex_lock(&kvm->irq_lock); |
223 | if (irq_source_id < 0 || | 207 | if (irq_source_id < 0 || |
@@ -230,9 +214,7 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id) | |||
230 | goto unlock; | 214 | goto unlock; |
231 | 215 | ||
232 | kvm_ioapic_clear_all(kvm->arch.vioapic, irq_source_id); | 216 | kvm_ioapic_clear_all(kvm->arch.vioapic, irq_source_id); |
233 | #ifdef CONFIG_X86 | ||
234 | kvm_pic_clear_all(pic_irqchip(kvm), irq_source_id); | 217 | kvm_pic_clear_all(pic_irqchip(kvm), irq_source_id); |
235 | #endif | ||
236 | unlock: | 218 | unlock: |
237 | mutex_unlock(&kvm->irq_lock); | 219 | mutex_unlock(&kvm->irq_lock); |
238 | } | 220 | } |
@@ -242,7 +224,7 @@ void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq, | |||
242 | { | 224 | { |
243 | mutex_lock(&kvm->irq_lock); | 225 | mutex_lock(&kvm->irq_lock); |
244 | kimn->irq = irq; | 226 | kimn->irq = irq; |
245 | hlist_add_head_rcu(&kimn->link, &kvm->mask_notifier_list); | 227 | hlist_add_head_rcu(&kimn->link, &kvm->arch.mask_notifier_list); |
246 | mutex_unlock(&kvm->irq_lock); | 228 | mutex_unlock(&kvm->irq_lock); |
247 | } | 229 | } |
248 | 230 | ||
@@ -264,7 +246,7 @@ void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin, | |||
264 | idx = srcu_read_lock(&kvm->irq_srcu); | 246 | idx = srcu_read_lock(&kvm->irq_srcu); |
265 | gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin); | 247 | gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin); |
266 | if (gsi != -1) | 248 | if (gsi != -1) |
267 | hlist_for_each_entry_rcu(kimn, &kvm->mask_notifier_list, link) | 249 | hlist_for_each_entry_rcu(kimn, &kvm->arch.mask_notifier_list, link) |
268 | if (kimn->irq == gsi) | 250 | if (kimn->irq == gsi) |
269 | kimn->func(kimn, mask); | 251 | kimn->func(kimn, mask); |
270 | srcu_read_unlock(&kvm->irq_srcu, idx); | 252 | srcu_read_unlock(&kvm->irq_srcu, idx); |
@@ -322,16 +304,11 @@ out: | |||
322 | .u.irqchip = { .irqchip = KVM_IRQCHIP_IOAPIC, .pin = (irq) } } | 304 | .u.irqchip = { .irqchip = KVM_IRQCHIP_IOAPIC, .pin = (irq) } } |
323 | #define ROUTING_ENTRY1(irq) IOAPIC_ROUTING_ENTRY(irq) | 305 | #define ROUTING_ENTRY1(irq) IOAPIC_ROUTING_ENTRY(irq) |
324 | 306 | ||
325 | #ifdef CONFIG_X86 | 307 | #define PIC_ROUTING_ENTRY(irq) \ |
326 | # define PIC_ROUTING_ENTRY(irq) \ | ||
327 | { .gsi = irq, .type = KVM_IRQ_ROUTING_IRQCHIP, \ | 308 | { .gsi = irq, .type = KVM_IRQ_ROUTING_IRQCHIP, \ |
328 | .u.irqchip = { .irqchip = SELECT_PIC(irq), .pin = (irq) % 8 } } | 309 | .u.irqchip = { .irqchip = SELECT_PIC(irq), .pin = (irq) % 8 } } |
329 | # define ROUTING_ENTRY2(irq) \ | 310 | #define ROUTING_ENTRY2(irq) \ |
330 | IOAPIC_ROUTING_ENTRY(irq), PIC_ROUTING_ENTRY(irq) | 311 | IOAPIC_ROUTING_ENTRY(irq), PIC_ROUTING_ENTRY(irq) |
331 | #else | ||
332 | # define ROUTING_ENTRY2(irq) \ | ||
333 | IOAPIC_ROUTING_ENTRY(irq) | ||
334 | #endif | ||
335 | 312 | ||
336 | static const struct kvm_irq_routing_entry default_routing[] = { | 313 | static const struct kvm_irq_routing_entry default_routing[] = { |
337 | ROUTING_ENTRY2(0), ROUTING_ENTRY2(1), | 314 | ROUTING_ENTRY2(0), ROUTING_ENTRY2(1), |
@@ -346,20 +323,6 @@ static const struct kvm_irq_routing_entry default_routing[] = { | |||
346 | ROUTING_ENTRY1(18), ROUTING_ENTRY1(19), | 323 | ROUTING_ENTRY1(18), ROUTING_ENTRY1(19), |
347 | ROUTING_ENTRY1(20), ROUTING_ENTRY1(21), | 324 | ROUTING_ENTRY1(20), ROUTING_ENTRY1(21), |
348 | ROUTING_ENTRY1(22), ROUTING_ENTRY1(23), | 325 | ROUTING_ENTRY1(22), ROUTING_ENTRY1(23), |
349 | #ifdef CONFIG_IA64 | ||
350 | ROUTING_ENTRY1(24), ROUTING_ENTRY1(25), | ||
351 | ROUTING_ENTRY1(26), ROUTING_ENTRY1(27), | ||
352 | ROUTING_ENTRY1(28), ROUTING_ENTRY1(29), | ||
353 | ROUTING_ENTRY1(30), ROUTING_ENTRY1(31), | ||
354 | ROUTING_ENTRY1(32), ROUTING_ENTRY1(33), | ||
355 | ROUTING_ENTRY1(34), ROUTING_ENTRY1(35), | ||
356 | ROUTING_ENTRY1(36), ROUTING_ENTRY1(37), | ||
357 | ROUTING_ENTRY1(38), ROUTING_ENTRY1(39), | ||
358 | ROUTING_ENTRY1(40), ROUTING_ENTRY1(41), | ||
359 | ROUTING_ENTRY1(42), ROUTING_ENTRY1(43), | ||
360 | ROUTING_ENTRY1(44), ROUTING_ENTRY1(45), | ||
361 | ROUTING_ENTRY1(46), ROUTING_ENTRY1(47), | ||
362 | #endif | ||
363 | }; | 326 | }; |
364 | 327 | ||
365 | int kvm_setup_default_irq_routing(struct kvm *kvm) | 328 | int kvm_setup_default_irq_routing(struct kvm *kvm) |
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index b8345dd41b25..4f0c0b954686 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -68,6 +68,9 @@ | |||
68 | #define MAX_APIC_VECTOR 256 | 68 | #define MAX_APIC_VECTOR 256 |
69 | #define APIC_VECTORS_PER_REG 32 | 69 | #define APIC_VECTORS_PER_REG 32 |
70 | 70 | ||
71 | #define APIC_BROADCAST 0xFF | ||
72 | #define X2APIC_BROADCAST 0xFFFFFFFFul | ||
73 | |||
71 | #define VEC_POS(v) ((v) & (32 - 1)) | 74 | #define VEC_POS(v) ((v) & (32 - 1)) |
72 | #define REG_POS(v) (((v) >> 5) << 4) | 75 | #define REG_POS(v) (((v) >> 5) << 4) |
73 | 76 | ||
@@ -129,8 +132,6 @@ static inline int kvm_apic_id(struct kvm_lapic *apic) | |||
129 | return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff; | 132 | return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff; |
130 | } | 133 | } |
131 | 134 | ||
132 | #define KVM_X2APIC_CID_BITS 0 | ||
133 | |||
134 | static void recalculate_apic_map(struct kvm *kvm) | 135 | static void recalculate_apic_map(struct kvm *kvm) |
135 | { | 136 | { |
136 | struct kvm_apic_map *new, *old = NULL; | 137 | struct kvm_apic_map *new, *old = NULL; |
@@ -149,42 +150,56 @@ static void recalculate_apic_map(struct kvm *kvm) | |||
149 | new->cid_shift = 8; | 150 | new->cid_shift = 8; |
150 | new->cid_mask = 0; | 151 | new->cid_mask = 0; |
151 | new->lid_mask = 0xff; | 152 | new->lid_mask = 0xff; |
153 | new->broadcast = APIC_BROADCAST; | ||
152 | 154 | ||
153 | kvm_for_each_vcpu(i, vcpu, kvm) { | 155 | kvm_for_each_vcpu(i, vcpu, kvm) { |
154 | struct kvm_lapic *apic = vcpu->arch.apic; | 156 | struct kvm_lapic *apic = vcpu->arch.apic; |
155 | u16 cid, lid; | ||
156 | u32 ldr; | ||
157 | 157 | ||
158 | if (!kvm_apic_present(vcpu)) | 158 | if (!kvm_apic_present(vcpu)) |
159 | continue; | 159 | continue; |
160 | 160 | ||
161 | if (apic_x2apic_mode(apic)) { | ||
162 | new->ldr_bits = 32; | ||
163 | new->cid_shift = 16; | ||
164 | new->cid_mask = new->lid_mask = 0xffff; | ||
165 | new->broadcast = X2APIC_BROADCAST; | ||
166 | } else if (kvm_apic_get_reg(apic, APIC_LDR)) { | ||
167 | if (kvm_apic_get_reg(apic, APIC_DFR) == | ||
168 | APIC_DFR_CLUSTER) { | ||
169 | new->cid_shift = 4; | ||
170 | new->cid_mask = 0xf; | ||
171 | new->lid_mask = 0xf; | ||
172 | } else { | ||
173 | new->cid_shift = 8; | ||
174 | new->cid_mask = 0; | ||
175 | new->lid_mask = 0xff; | ||
176 | } | ||
177 | } | ||
178 | |||
161 | /* | 179 | /* |
162 | * All APICs have to be configured in the same mode by an OS. | 180 | * All APICs have to be configured in the same mode by an OS. |
163 | * We take advatage of this while building logical id loockup | 181 | * We take advatage of this while building logical id loockup |
164 | * table. After reset APICs are in xapic/flat mode, so if we | 182 | * table. After reset APICs are in software disabled mode, so if |
165 | * find apic with different setting we assume this is the mode | 183 | * we find apic with different setting we assume this is the mode |
166 | * OS wants all apics to be in; build lookup table accordingly. | 184 | * OS wants all apics to be in; build lookup table accordingly. |
167 | */ | 185 | */ |
168 | if (apic_x2apic_mode(apic)) { | 186 | if (kvm_apic_sw_enabled(apic)) |
169 | new->ldr_bits = 32; | 187 | break; |
170 | new->cid_shift = 16; | 188 | } |
171 | new->cid_mask = (1 << KVM_X2APIC_CID_BITS) - 1; | ||
172 | new->lid_mask = 0xffff; | ||
173 | } else if (kvm_apic_sw_enabled(apic) && | ||
174 | !new->cid_mask /* flat mode */ && | ||
175 | kvm_apic_get_reg(apic, APIC_DFR) == APIC_DFR_CLUSTER) { | ||
176 | new->cid_shift = 4; | ||
177 | new->cid_mask = 0xf; | ||
178 | new->lid_mask = 0xf; | ||
179 | } | ||
180 | 189 | ||
181 | new->phys_map[kvm_apic_id(apic)] = apic; | 190 | kvm_for_each_vcpu(i, vcpu, kvm) { |
191 | struct kvm_lapic *apic = vcpu->arch.apic; | ||
192 | u16 cid, lid; | ||
193 | u32 ldr, aid; | ||
182 | 194 | ||
195 | aid = kvm_apic_id(apic); | ||
183 | ldr = kvm_apic_get_reg(apic, APIC_LDR); | 196 | ldr = kvm_apic_get_reg(apic, APIC_LDR); |
184 | cid = apic_cluster_id(new, ldr); | 197 | cid = apic_cluster_id(new, ldr); |
185 | lid = apic_logical_id(new, ldr); | 198 | lid = apic_logical_id(new, ldr); |
186 | 199 | ||
187 | if (lid) | 200 | if (aid < ARRAY_SIZE(new->phys_map)) |
201 | new->phys_map[aid] = apic; | ||
202 | if (lid && cid < ARRAY_SIZE(new->logical_map)) | ||
188 | new->logical_map[cid][ffs(lid) - 1] = apic; | 203 | new->logical_map[cid][ffs(lid) - 1] = apic; |
189 | } | 204 | } |
190 | out: | 205 | out: |
@@ -201,11 +216,13 @@ out: | |||
201 | 216 | ||
202 | static inline void apic_set_spiv(struct kvm_lapic *apic, u32 val) | 217 | static inline void apic_set_spiv(struct kvm_lapic *apic, u32 val) |
203 | { | 218 | { |
204 | u32 prev = kvm_apic_get_reg(apic, APIC_SPIV); | 219 | bool enabled = val & APIC_SPIV_APIC_ENABLED; |
205 | 220 | ||
206 | apic_set_reg(apic, APIC_SPIV, val); | 221 | apic_set_reg(apic, APIC_SPIV, val); |
207 | if ((prev ^ val) & APIC_SPIV_APIC_ENABLED) { | 222 | |
208 | if (val & APIC_SPIV_APIC_ENABLED) { | 223 | if (enabled != apic->sw_enabled) { |
224 | apic->sw_enabled = enabled; | ||
225 | if (enabled) { | ||
209 | static_key_slow_dec_deferred(&apic_sw_disabled); | 226 | static_key_slow_dec_deferred(&apic_sw_disabled); |
210 | recalculate_apic_map(apic->vcpu->kvm); | 227 | recalculate_apic_map(apic->vcpu->kvm); |
211 | } else | 228 | } else |
@@ -237,21 +254,17 @@ static inline int apic_lvt_vector(struct kvm_lapic *apic, int lvt_type) | |||
237 | 254 | ||
238 | static inline int apic_lvtt_oneshot(struct kvm_lapic *apic) | 255 | static inline int apic_lvtt_oneshot(struct kvm_lapic *apic) |
239 | { | 256 | { |
240 | return ((kvm_apic_get_reg(apic, APIC_LVTT) & | 257 | return apic->lapic_timer.timer_mode == APIC_LVT_TIMER_ONESHOT; |
241 | apic->lapic_timer.timer_mode_mask) == APIC_LVT_TIMER_ONESHOT); | ||
242 | } | 258 | } |
243 | 259 | ||
244 | static inline int apic_lvtt_period(struct kvm_lapic *apic) | 260 | static inline int apic_lvtt_period(struct kvm_lapic *apic) |
245 | { | 261 | { |
246 | return ((kvm_apic_get_reg(apic, APIC_LVTT) & | 262 | return apic->lapic_timer.timer_mode == APIC_LVT_TIMER_PERIODIC; |
247 | apic->lapic_timer.timer_mode_mask) == APIC_LVT_TIMER_PERIODIC); | ||
248 | } | 263 | } |
249 | 264 | ||
250 | static inline int apic_lvtt_tscdeadline(struct kvm_lapic *apic) | 265 | static inline int apic_lvtt_tscdeadline(struct kvm_lapic *apic) |
251 | { | 266 | { |
252 | return ((kvm_apic_get_reg(apic, APIC_LVTT) & | 267 | return apic->lapic_timer.timer_mode == APIC_LVT_TIMER_TSCDEADLINE; |
253 | apic->lapic_timer.timer_mode_mask) == | ||
254 | APIC_LVT_TIMER_TSCDEADLINE); | ||
255 | } | 268 | } |
256 | 269 | ||
257 | static inline int apic_lvt_nmi_mode(u32 lvt_val) | 270 | static inline int apic_lvt_nmi_mode(u32 lvt_val) |
@@ -326,8 +339,12 @@ EXPORT_SYMBOL_GPL(kvm_apic_update_irr); | |||
326 | 339 | ||
327 | static inline void apic_set_irr(int vec, struct kvm_lapic *apic) | 340 | static inline void apic_set_irr(int vec, struct kvm_lapic *apic) |
328 | { | 341 | { |
329 | apic->irr_pending = true; | ||
330 | apic_set_vector(vec, apic->regs + APIC_IRR); | 342 | apic_set_vector(vec, apic->regs + APIC_IRR); |
343 | /* | ||
344 | * irr_pending must be true if any interrupt is pending; set it after | ||
345 | * APIC_IRR to avoid race with apic_clear_irr | ||
346 | */ | ||
347 | apic->irr_pending = true; | ||
331 | } | 348 | } |
332 | 349 | ||
333 | static inline int apic_search_irr(struct kvm_lapic *apic) | 350 | static inline int apic_search_irr(struct kvm_lapic *apic) |
@@ -359,13 +376,15 @@ static inline void apic_clear_irr(int vec, struct kvm_lapic *apic) | |||
359 | 376 | ||
360 | vcpu = apic->vcpu; | 377 | vcpu = apic->vcpu; |
361 | 378 | ||
362 | apic_clear_vector(vec, apic->regs + APIC_IRR); | 379 | if (unlikely(kvm_apic_vid_enabled(vcpu->kvm))) { |
363 | if (unlikely(kvm_apic_vid_enabled(vcpu->kvm))) | ||
364 | /* try to update RVI */ | 380 | /* try to update RVI */ |
381 | apic_clear_vector(vec, apic->regs + APIC_IRR); | ||
365 | kvm_make_request(KVM_REQ_EVENT, vcpu); | 382 | kvm_make_request(KVM_REQ_EVENT, vcpu); |
366 | else { | 383 | } else { |
367 | vec = apic_search_irr(apic); | 384 | apic->irr_pending = false; |
368 | apic->irr_pending = (vec != -1); | 385 | apic_clear_vector(vec, apic->regs + APIC_IRR); |
386 | if (apic_search_irr(apic) != -1) | ||
387 | apic->irr_pending = true; | ||
369 | } | 388 | } |
370 | } | 389 | } |
371 | 390 | ||
@@ -558,16 +577,25 @@ static void apic_set_tpr(struct kvm_lapic *apic, u32 tpr) | |||
558 | apic_update_ppr(apic); | 577 | apic_update_ppr(apic); |
559 | } | 578 | } |
560 | 579 | ||
561 | int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest) | 580 | static int kvm_apic_broadcast(struct kvm_lapic *apic, u32 dest) |
581 | { | ||
582 | return dest == (apic_x2apic_mode(apic) ? | ||
583 | X2APIC_BROADCAST : APIC_BROADCAST); | ||
584 | } | ||
585 | |||
586 | int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u32 dest) | ||
562 | { | 587 | { |
563 | return dest == 0xff || kvm_apic_id(apic) == dest; | 588 | return kvm_apic_id(apic) == dest || kvm_apic_broadcast(apic, dest); |
564 | } | 589 | } |
565 | 590 | ||
566 | int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda) | 591 | int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u32 mda) |
567 | { | 592 | { |
568 | int result = 0; | 593 | int result = 0; |
569 | u32 logical_id; | 594 | u32 logical_id; |
570 | 595 | ||
596 | if (kvm_apic_broadcast(apic, mda)) | ||
597 | return 1; | ||
598 | |||
571 | if (apic_x2apic_mode(apic)) { | 599 | if (apic_x2apic_mode(apic)) { |
572 | logical_id = kvm_apic_get_reg(apic, APIC_LDR); | 600 | logical_id = kvm_apic_get_reg(apic, APIC_LDR); |
573 | return logical_id & mda; | 601 | return logical_id & mda; |
@@ -595,7 +623,7 @@ int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda) | |||
595 | } | 623 | } |
596 | 624 | ||
597 | int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, | 625 | int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, |
598 | int short_hand, int dest, int dest_mode) | 626 | int short_hand, unsigned int dest, int dest_mode) |
599 | { | 627 | { |
600 | int result = 0; | 628 | int result = 0; |
601 | struct kvm_lapic *target = vcpu->arch.apic; | 629 | struct kvm_lapic *target = vcpu->arch.apic; |
@@ -657,15 +685,24 @@ bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src, | |||
657 | if (!map) | 685 | if (!map) |
658 | goto out; | 686 | goto out; |
659 | 687 | ||
688 | if (irq->dest_id == map->broadcast) | ||
689 | goto out; | ||
690 | |||
691 | ret = true; | ||
692 | |||
660 | if (irq->dest_mode == 0) { /* physical mode */ | 693 | if (irq->dest_mode == 0) { /* physical mode */ |
661 | if (irq->delivery_mode == APIC_DM_LOWEST || | 694 | if (irq->dest_id >= ARRAY_SIZE(map->phys_map)) |
662 | irq->dest_id == 0xff) | ||
663 | goto out; | 695 | goto out; |
664 | dst = &map->phys_map[irq->dest_id & 0xff]; | 696 | |
697 | dst = &map->phys_map[irq->dest_id]; | ||
665 | } else { | 698 | } else { |
666 | u32 mda = irq->dest_id << (32 - map->ldr_bits); | 699 | u32 mda = irq->dest_id << (32 - map->ldr_bits); |
700 | u16 cid = apic_cluster_id(map, mda); | ||
701 | |||
702 | if (cid >= ARRAY_SIZE(map->logical_map)) | ||
703 | goto out; | ||
667 | 704 | ||
668 | dst = map->logical_map[apic_cluster_id(map, mda)]; | 705 | dst = map->logical_map[cid]; |
669 | 706 | ||
670 | bitmap = apic_logical_id(map, mda); | 707 | bitmap = apic_logical_id(map, mda); |
671 | 708 | ||
@@ -691,8 +728,6 @@ bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src, | |||
691 | *r = 0; | 728 | *r = 0; |
692 | *r += kvm_apic_set_irq(dst[i]->vcpu, irq, dest_map); | 729 | *r += kvm_apic_set_irq(dst[i]->vcpu, irq, dest_map); |
693 | } | 730 | } |
694 | |||
695 | ret = true; | ||
696 | out: | 731 | out: |
697 | rcu_read_unlock(); | 732 | rcu_read_unlock(); |
698 | return ret; | 733 | return ret; |
@@ -1034,6 +1069,26 @@ static void update_divide_count(struct kvm_lapic *apic) | |||
1034 | apic->divide_count); | 1069 | apic->divide_count); |
1035 | } | 1070 | } |
1036 | 1071 | ||
1072 | static void apic_timer_expired(struct kvm_lapic *apic) | ||
1073 | { | ||
1074 | struct kvm_vcpu *vcpu = apic->vcpu; | ||
1075 | wait_queue_head_t *q = &vcpu->wq; | ||
1076 | |||
1077 | /* | ||
1078 | * Note: KVM_REQ_PENDING_TIMER is implicitly checked in | ||
1079 | * vcpu_enter_guest. | ||
1080 | */ | ||
1081 | if (atomic_read(&apic->lapic_timer.pending)) | ||
1082 | return; | ||
1083 | |||
1084 | atomic_inc(&apic->lapic_timer.pending); | ||
1085 | /* FIXME: this code should not know anything about vcpus */ | ||
1086 | kvm_make_request(KVM_REQ_PENDING_TIMER, vcpu); | ||
1087 | |||
1088 | if (waitqueue_active(q)) | ||
1089 | wake_up_interruptible(q); | ||
1090 | } | ||
1091 | |||
1037 | static void start_apic_timer(struct kvm_lapic *apic) | 1092 | static void start_apic_timer(struct kvm_lapic *apic) |
1038 | { | 1093 | { |
1039 | ktime_t now; | 1094 | ktime_t now; |
@@ -1096,9 +1151,10 @@ static void start_apic_timer(struct kvm_lapic *apic) | |||
1096 | if (likely(tscdeadline > guest_tsc)) { | 1151 | if (likely(tscdeadline > guest_tsc)) { |
1097 | ns = (tscdeadline - guest_tsc) * 1000000ULL; | 1152 | ns = (tscdeadline - guest_tsc) * 1000000ULL; |
1098 | do_div(ns, this_tsc_khz); | 1153 | do_div(ns, this_tsc_khz); |
1099 | } | 1154 | hrtimer_start(&apic->lapic_timer.timer, |
1100 | hrtimer_start(&apic->lapic_timer.timer, | 1155 | ktime_add_ns(now, ns), HRTIMER_MODE_ABS); |
1101 | ktime_add_ns(now, ns), HRTIMER_MODE_ABS); | 1156 | } else |
1157 | apic_timer_expired(apic); | ||
1102 | 1158 | ||
1103 | local_irq_restore(flags); | 1159 | local_irq_restore(flags); |
1104 | } | 1160 | } |
@@ -1203,17 +1259,20 @@ static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) | |||
1203 | 1259 | ||
1204 | break; | 1260 | break; |
1205 | 1261 | ||
1206 | case APIC_LVTT: | 1262 | case APIC_LVTT: { |
1207 | if ((kvm_apic_get_reg(apic, APIC_LVTT) & | 1263 | u32 timer_mode = val & apic->lapic_timer.timer_mode_mask; |
1208 | apic->lapic_timer.timer_mode_mask) != | 1264 | |
1209 | (val & apic->lapic_timer.timer_mode_mask)) | 1265 | if (apic->lapic_timer.timer_mode != timer_mode) { |
1266 | apic->lapic_timer.timer_mode = timer_mode; | ||
1210 | hrtimer_cancel(&apic->lapic_timer.timer); | 1267 | hrtimer_cancel(&apic->lapic_timer.timer); |
1268 | } | ||
1211 | 1269 | ||
1212 | if (!kvm_apic_sw_enabled(apic)) | 1270 | if (!kvm_apic_sw_enabled(apic)) |
1213 | val |= APIC_LVT_MASKED; | 1271 | val |= APIC_LVT_MASKED; |
1214 | val &= (apic_lvt_mask[0] | apic->lapic_timer.timer_mode_mask); | 1272 | val &= (apic_lvt_mask[0] | apic->lapic_timer.timer_mode_mask); |
1215 | apic_set_reg(apic, APIC_LVTT, val); | 1273 | apic_set_reg(apic, APIC_LVTT, val); |
1216 | break; | 1274 | break; |
1275 | } | ||
1217 | 1276 | ||
1218 | case APIC_TMICT: | 1277 | case APIC_TMICT: |
1219 | if (apic_lvtt_tscdeadline(apic)) | 1278 | if (apic_lvtt_tscdeadline(apic)) |
@@ -1320,7 +1379,7 @@ void kvm_free_lapic(struct kvm_vcpu *vcpu) | |||
1320 | if (!(vcpu->arch.apic_base & MSR_IA32_APICBASE_ENABLE)) | 1379 | if (!(vcpu->arch.apic_base & MSR_IA32_APICBASE_ENABLE)) |
1321 | static_key_slow_dec_deferred(&apic_hw_disabled); | 1380 | static_key_slow_dec_deferred(&apic_hw_disabled); |
1322 | 1381 | ||
1323 | if (!(kvm_apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_APIC_ENABLED)) | 1382 | if (!apic->sw_enabled) |
1324 | static_key_slow_dec_deferred(&apic_sw_disabled); | 1383 | static_key_slow_dec_deferred(&apic_sw_disabled); |
1325 | 1384 | ||
1326 | if (apic->regs) | 1385 | if (apic->regs) |
@@ -1355,9 +1414,6 @@ void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, u64 data) | |||
1355 | return; | 1414 | return; |
1356 | 1415 | ||
1357 | hrtimer_cancel(&apic->lapic_timer.timer); | 1416 | hrtimer_cancel(&apic->lapic_timer.timer); |
1358 | /* Inject here so clearing tscdeadline won't override new value */ | ||
1359 | if (apic_has_pending_timer(vcpu)) | ||
1360 | kvm_inject_apic_timer_irqs(vcpu); | ||
1361 | apic->lapic_timer.tscdeadline = data; | 1417 | apic->lapic_timer.tscdeadline = data; |
1362 | start_apic_timer(apic); | 1418 | start_apic_timer(apic); |
1363 | } | 1419 | } |
@@ -1422,6 +1478,10 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) | |||
1422 | apic->base_address = apic->vcpu->arch.apic_base & | 1478 | apic->base_address = apic->vcpu->arch.apic_base & |
1423 | MSR_IA32_APICBASE_BASE; | 1479 | MSR_IA32_APICBASE_BASE; |
1424 | 1480 | ||
1481 | if ((value & MSR_IA32_APICBASE_ENABLE) && | ||
1482 | apic->base_address != APIC_DEFAULT_PHYS_BASE) | ||
1483 | pr_warn_once("APIC base relocation is unsupported by KVM"); | ||
1484 | |||
1425 | /* with FSB delivery interrupt, we can restart APIC functionality */ | 1485 | /* with FSB delivery interrupt, we can restart APIC functionality */ |
1426 | apic_debug("apic base msr is 0x%016" PRIx64 ", and base address is " | 1486 | apic_debug("apic base msr is 0x%016" PRIx64 ", and base address is " |
1427 | "0x%lx.\n", apic->vcpu->arch.apic_base, apic->base_address); | 1487 | "0x%lx.\n", apic->vcpu->arch.apic_base, apic->base_address); |
@@ -1447,6 +1507,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu) | |||
1447 | 1507 | ||
1448 | for (i = 0; i < APIC_LVT_NUM; i++) | 1508 | for (i = 0; i < APIC_LVT_NUM; i++) |
1449 | apic_set_reg(apic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED); | 1509 | apic_set_reg(apic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED); |
1510 | apic->lapic_timer.timer_mode = 0; | ||
1450 | apic_set_reg(apic, APIC_LVT0, | 1511 | apic_set_reg(apic, APIC_LVT0, |
1451 | SET_APIC_DELIVERY_MODE(0, APIC_MODE_EXTINT)); | 1512 | SET_APIC_DELIVERY_MODE(0, APIC_MODE_EXTINT)); |
1452 | 1513 | ||
@@ -1538,23 +1599,8 @@ static enum hrtimer_restart apic_timer_fn(struct hrtimer *data) | |||
1538 | { | 1599 | { |
1539 | struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer); | 1600 | struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer); |
1540 | struct kvm_lapic *apic = container_of(ktimer, struct kvm_lapic, lapic_timer); | 1601 | struct kvm_lapic *apic = container_of(ktimer, struct kvm_lapic, lapic_timer); |
1541 | struct kvm_vcpu *vcpu = apic->vcpu; | ||
1542 | wait_queue_head_t *q = &vcpu->wq; | ||
1543 | |||
1544 | /* | ||
1545 | * There is a race window between reading and incrementing, but we do | ||
1546 | * not care about potentially losing timer events in the !reinject | ||
1547 | * case anyway. Note: KVM_REQ_PENDING_TIMER is implicitly checked | ||
1548 | * in vcpu_enter_guest. | ||
1549 | */ | ||
1550 | if (!atomic_read(&ktimer->pending)) { | ||
1551 | atomic_inc(&ktimer->pending); | ||
1552 | /* FIXME: this code should not know anything about vcpus */ | ||
1553 | kvm_make_request(KVM_REQ_PENDING_TIMER, vcpu); | ||
1554 | } | ||
1555 | 1602 | ||
1556 | if (waitqueue_active(q)) | 1603 | apic_timer_expired(apic); |
1557 | wake_up_interruptible(q); | ||
1558 | 1604 | ||
1559 | if (lapic_is_periodic(apic)) { | 1605 | if (lapic_is_periodic(apic)) { |
1560 | hrtimer_add_expires_ns(&ktimer->timer, ktimer->period); | 1606 | hrtimer_add_expires_ns(&ktimer->timer, ktimer->period); |
@@ -1693,6 +1739,9 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu, | |||
1693 | apic->isr_count = kvm_apic_vid_enabled(vcpu->kvm) ? | 1739 | apic->isr_count = kvm_apic_vid_enabled(vcpu->kvm) ? |
1694 | 1 : count_vectors(apic->regs + APIC_ISR); | 1740 | 1 : count_vectors(apic->regs + APIC_ISR); |
1695 | apic->highest_isr_cache = -1; | 1741 | apic->highest_isr_cache = -1; |
1742 | if (kvm_x86_ops->hwapic_irr_update) | ||
1743 | kvm_x86_ops->hwapic_irr_update(vcpu, | ||
1744 | apic_find_highest_irr(apic)); | ||
1696 | kvm_x86_ops->hwapic_isr_update(vcpu->kvm, apic_find_highest_isr(apic)); | 1745 | kvm_x86_ops->hwapic_isr_update(vcpu->kvm, apic_find_highest_isr(apic)); |
1697 | kvm_make_request(KVM_REQ_EVENT, vcpu); | 1746 | kvm_make_request(KVM_REQ_EVENT, vcpu); |
1698 | kvm_rtc_eoi_tracking_restore_one(vcpu); | 1747 | kvm_rtc_eoi_tracking_restore_one(vcpu); |
@@ -1837,8 +1886,11 @@ int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data) | |||
1837 | if (!irqchip_in_kernel(vcpu->kvm) || !apic_x2apic_mode(apic)) | 1886 | if (!irqchip_in_kernel(vcpu->kvm) || !apic_x2apic_mode(apic)) |
1838 | return 1; | 1887 | return 1; |
1839 | 1888 | ||
1889 | if (reg == APIC_ICR2) | ||
1890 | return 1; | ||
1891 | |||
1840 | /* if this is ICR write vector before command */ | 1892 | /* if this is ICR write vector before command */ |
1841 | if (msr == 0x830) | 1893 | if (reg == APIC_ICR) |
1842 | apic_reg_write(apic, APIC_ICR2, (u32)(data >> 32)); | 1894 | apic_reg_write(apic, APIC_ICR2, (u32)(data >> 32)); |
1843 | return apic_reg_write(apic, reg, (u32)data); | 1895 | return apic_reg_write(apic, reg, (u32)data); |
1844 | } | 1896 | } |
@@ -1851,9 +1903,15 @@ int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data) | |||
1851 | if (!irqchip_in_kernel(vcpu->kvm) || !apic_x2apic_mode(apic)) | 1903 | if (!irqchip_in_kernel(vcpu->kvm) || !apic_x2apic_mode(apic)) |
1852 | return 1; | 1904 | return 1; |
1853 | 1905 | ||
1906 | if (reg == APIC_DFR || reg == APIC_ICR2) { | ||
1907 | apic_debug("KVM_APIC_READ: read x2apic reserved register %x\n", | ||
1908 | reg); | ||
1909 | return 1; | ||
1910 | } | ||
1911 | |||
1854 | if (apic_reg_read(apic, reg, 4, &low)) | 1912 | if (apic_reg_read(apic, reg, 4, &low)) |
1855 | return 1; | 1913 | return 1; |
1856 | if (msr == 0x830) | 1914 | if (reg == APIC_ICR) |
1857 | apic_reg_read(apic, APIC_ICR2, 4, &high); | 1915 | apic_reg_read(apic, APIC_ICR2, 4, &high); |
1858 | 1916 | ||
1859 | *data = (((u64)high) << 32) | low; | 1917 | *data = (((u64)high) << 32) | low; |
@@ -1908,7 +1966,7 @@ int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data) | |||
1908 | void kvm_apic_accept_events(struct kvm_vcpu *vcpu) | 1966 | void kvm_apic_accept_events(struct kvm_vcpu *vcpu) |
1909 | { | 1967 | { |
1910 | struct kvm_lapic *apic = vcpu->arch.apic; | 1968 | struct kvm_lapic *apic = vcpu->arch.apic; |
1911 | unsigned int sipi_vector; | 1969 | u8 sipi_vector; |
1912 | unsigned long pe; | 1970 | unsigned long pe; |
1913 | 1971 | ||
1914 | if (!kvm_vcpu_has_lapic(vcpu) || !apic->pending_events) | 1972 | if (!kvm_vcpu_has_lapic(vcpu) || !apic->pending_events) |
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 6a11845fd8b9..c674fce53cf9 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h | |||
@@ -11,6 +11,7 @@ | |||
11 | struct kvm_timer { | 11 | struct kvm_timer { |
12 | struct hrtimer timer; | 12 | struct hrtimer timer; |
13 | s64 period; /* unit: ns */ | 13 | s64 period; /* unit: ns */ |
14 | u32 timer_mode; | ||
14 | u32 timer_mode_mask; | 15 | u32 timer_mode_mask; |
15 | u64 tscdeadline; | 16 | u64 tscdeadline; |
16 | atomic_t pending; /* accumulated triggered timers */ | 17 | atomic_t pending; /* accumulated triggered timers */ |
@@ -22,6 +23,7 @@ struct kvm_lapic { | |||
22 | struct kvm_timer lapic_timer; | 23 | struct kvm_timer lapic_timer; |
23 | u32 divide_count; | 24 | u32 divide_count; |
24 | struct kvm_vcpu *vcpu; | 25 | struct kvm_vcpu *vcpu; |
26 | bool sw_enabled; | ||
25 | bool irr_pending; | 27 | bool irr_pending; |
26 | /* Number of bits set in ISR. */ | 28 | /* Number of bits set in ISR. */ |
27 | s16 isr_count; | 29 | s16 isr_count; |
@@ -55,8 +57,8 @@ void kvm_apic_set_version(struct kvm_vcpu *vcpu); | |||
55 | 57 | ||
56 | void kvm_apic_update_tmr(struct kvm_vcpu *vcpu, u32 *tmr); | 58 | void kvm_apic_update_tmr(struct kvm_vcpu *vcpu, u32 *tmr); |
57 | void kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir); | 59 | void kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir); |
58 | int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest); | 60 | int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u32 dest); |
59 | int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda); | 61 | int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u32 mda); |
60 | int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq, | 62 | int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq, |
61 | unsigned long *dest_map); | 63 | unsigned long *dest_map); |
62 | int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type); | 64 | int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type); |
@@ -119,11 +121,11 @@ static inline int kvm_apic_hw_enabled(struct kvm_lapic *apic) | |||
119 | 121 | ||
120 | extern struct static_key_deferred apic_sw_disabled; | 122 | extern struct static_key_deferred apic_sw_disabled; |
121 | 123 | ||
122 | static inline int kvm_apic_sw_enabled(struct kvm_lapic *apic) | 124 | static inline bool kvm_apic_sw_enabled(struct kvm_lapic *apic) |
123 | { | 125 | { |
124 | if (static_key_false(&apic_sw_disabled.key)) | 126 | if (static_key_false(&apic_sw_disabled.key)) |
125 | return kvm_apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_APIC_ENABLED; | 127 | return apic->sw_enabled; |
126 | return APIC_SPIV_APIC_ENABLED; | 128 | return true; |
127 | } | 129 | } |
128 | 130 | ||
129 | static inline bool kvm_apic_present(struct kvm_vcpu *vcpu) | 131 | static inline bool kvm_apic_present(struct kvm_vcpu *vcpu) |
@@ -152,8 +154,6 @@ static inline u16 apic_cluster_id(struct kvm_apic_map *map, u32 ldr) | |||
152 | ldr >>= 32 - map->ldr_bits; | 154 | ldr >>= 32 - map->ldr_bits; |
153 | cid = (ldr >> map->cid_shift) & map->cid_mask; | 155 | cid = (ldr >> map->cid_shift) & map->cid_mask; |
154 | 156 | ||
155 | BUG_ON(cid >= ARRAY_SIZE(map->logical_map)); | ||
156 | |||
157 | return cid; | 157 | return cid; |
158 | } | 158 | } |
159 | 159 | ||
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 978f402006ee..10fbed126b11 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -214,13 +214,12 @@ EXPORT_SYMBOL_GPL(kvm_mmu_set_mmio_spte_mask); | |||
214 | #define MMIO_GEN_LOW_SHIFT 10 | 214 | #define MMIO_GEN_LOW_SHIFT 10 |
215 | #define MMIO_GEN_LOW_MASK ((1 << MMIO_GEN_LOW_SHIFT) - 2) | 215 | #define MMIO_GEN_LOW_MASK ((1 << MMIO_GEN_LOW_SHIFT) - 2) |
216 | #define MMIO_GEN_MASK ((1 << MMIO_GEN_SHIFT) - 1) | 216 | #define MMIO_GEN_MASK ((1 << MMIO_GEN_SHIFT) - 1) |
217 | #define MMIO_MAX_GEN ((1 << MMIO_GEN_SHIFT) - 1) | ||
218 | 217 | ||
219 | static u64 generation_mmio_spte_mask(unsigned int gen) | 218 | static u64 generation_mmio_spte_mask(unsigned int gen) |
220 | { | 219 | { |
221 | u64 mask; | 220 | u64 mask; |
222 | 221 | ||
223 | WARN_ON(gen > MMIO_MAX_GEN); | 222 | WARN_ON(gen & ~MMIO_GEN_MASK); |
224 | 223 | ||
225 | mask = (gen & MMIO_GEN_LOW_MASK) << MMIO_SPTE_GEN_LOW_SHIFT; | 224 | mask = (gen & MMIO_GEN_LOW_MASK) << MMIO_SPTE_GEN_LOW_SHIFT; |
226 | mask |= ((u64)gen >> MMIO_GEN_LOW_SHIFT) << MMIO_SPTE_GEN_HIGH_SHIFT; | 225 | mask |= ((u64)gen >> MMIO_GEN_LOW_SHIFT) << MMIO_SPTE_GEN_HIGH_SHIFT; |
@@ -263,13 +262,13 @@ static bool is_mmio_spte(u64 spte) | |||
263 | 262 | ||
264 | static gfn_t get_mmio_spte_gfn(u64 spte) | 263 | static gfn_t get_mmio_spte_gfn(u64 spte) |
265 | { | 264 | { |
266 | u64 mask = generation_mmio_spte_mask(MMIO_MAX_GEN) | shadow_mmio_mask; | 265 | u64 mask = generation_mmio_spte_mask(MMIO_GEN_MASK) | shadow_mmio_mask; |
267 | return (spte & ~mask) >> PAGE_SHIFT; | 266 | return (spte & ~mask) >> PAGE_SHIFT; |
268 | } | 267 | } |
269 | 268 | ||
270 | static unsigned get_mmio_spte_access(u64 spte) | 269 | static unsigned get_mmio_spte_access(u64 spte) |
271 | { | 270 | { |
272 | u64 mask = generation_mmio_spte_mask(MMIO_MAX_GEN) | shadow_mmio_mask; | 271 | u64 mask = generation_mmio_spte_mask(MMIO_GEN_MASK) | shadow_mmio_mask; |
273 | return (spte & ~mask) & ~PAGE_MASK; | 272 | return (spte & ~mask) & ~PAGE_MASK; |
274 | } | 273 | } |
275 | 274 | ||
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 7527cefc5a43..41dd0387cccb 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -1056,9 +1056,11 @@ static void svm_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment, bool ho | |||
1056 | { | 1056 | { |
1057 | struct vcpu_svm *svm = to_svm(vcpu); | 1057 | struct vcpu_svm *svm = to_svm(vcpu); |
1058 | 1058 | ||
1059 | WARN_ON(adjustment < 0); | 1059 | if (host) { |
1060 | if (host) | 1060 | if (svm->tsc_ratio != TSC_RATIO_DEFAULT) |
1061 | adjustment = svm_scale_tsc(vcpu, adjustment); | 1061 | WARN_ON(adjustment < 0); |
1062 | adjustment = svm_scale_tsc(vcpu, (u64)adjustment); | ||
1063 | } | ||
1062 | 1064 | ||
1063 | svm->vmcb->control.tsc_offset += adjustment; | 1065 | svm->vmcb->control.tsc_offset += adjustment; |
1064 | if (is_guest_mode(vcpu)) | 1066 | if (is_guest_mode(vcpu)) |
@@ -2999,7 +3001,6 @@ static int dr_interception(struct vcpu_svm *svm) | |||
2999 | { | 3001 | { |
3000 | int reg, dr; | 3002 | int reg, dr; |
3001 | unsigned long val; | 3003 | unsigned long val; |
3002 | int err; | ||
3003 | 3004 | ||
3004 | if (svm->vcpu.guest_debug == 0) { | 3005 | if (svm->vcpu.guest_debug == 0) { |
3005 | /* | 3006 | /* |
@@ -3019,12 +3020,15 @@ static int dr_interception(struct vcpu_svm *svm) | |||
3019 | dr = svm->vmcb->control.exit_code - SVM_EXIT_READ_DR0; | 3020 | dr = svm->vmcb->control.exit_code - SVM_EXIT_READ_DR0; |
3020 | 3021 | ||
3021 | if (dr >= 16) { /* mov to DRn */ | 3022 | if (dr >= 16) { /* mov to DRn */ |
3023 | if (!kvm_require_dr(&svm->vcpu, dr - 16)) | ||
3024 | return 1; | ||
3022 | val = kvm_register_read(&svm->vcpu, reg); | 3025 | val = kvm_register_read(&svm->vcpu, reg); |
3023 | kvm_set_dr(&svm->vcpu, dr - 16, val); | 3026 | kvm_set_dr(&svm->vcpu, dr - 16, val); |
3024 | } else { | 3027 | } else { |
3025 | err = kvm_get_dr(&svm->vcpu, dr, &val); | 3028 | if (!kvm_require_dr(&svm->vcpu, dr)) |
3026 | if (!err) | 3029 | return 1; |
3027 | kvm_register_write(&svm->vcpu, reg, val); | 3030 | kvm_get_dr(&svm->vcpu, dr, &val); |
3031 | kvm_register_write(&svm->vcpu, reg, val); | ||
3028 | } | 3032 | } |
3029 | 3033 | ||
3030 | skip_emulated_instruction(&svm->vcpu); | 3034 | skip_emulated_instruction(&svm->vcpu); |
@@ -4123,6 +4127,11 @@ static bool svm_mpx_supported(void) | |||
4123 | return false; | 4127 | return false; |
4124 | } | 4128 | } |
4125 | 4129 | ||
4130 | static bool svm_xsaves_supported(void) | ||
4131 | { | ||
4132 | return false; | ||
4133 | } | ||
4134 | |||
4126 | static bool svm_has_wbinvd_exit(void) | 4135 | static bool svm_has_wbinvd_exit(void) |
4127 | { | 4136 | { |
4128 | return true; | 4137 | return true; |
@@ -4410,6 +4419,7 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
4410 | .rdtscp_supported = svm_rdtscp_supported, | 4419 | .rdtscp_supported = svm_rdtscp_supported, |
4411 | .invpcid_supported = svm_invpcid_supported, | 4420 | .invpcid_supported = svm_invpcid_supported, |
4412 | .mpx_supported = svm_mpx_supported, | 4421 | .mpx_supported = svm_mpx_supported, |
4422 | .xsaves_supported = svm_xsaves_supported, | ||
4413 | 4423 | ||
4414 | .set_supported_cpuid = svm_set_supported_cpuid, | 4424 | .set_supported_cpuid = svm_set_supported_cpuid, |
4415 | 4425 | ||
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index 6b06ab8748dd..c2a34bb5ad93 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <asm/vmx.h> | 5 | #include <asm/vmx.h> |
6 | #include <asm/svm.h> | 6 | #include <asm/svm.h> |
7 | #include <asm/clocksource.h> | 7 | #include <asm/clocksource.h> |
8 | #include <asm/pvclock-abi.h> | ||
8 | 9 | ||
9 | #undef TRACE_SYSTEM | 10 | #undef TRACE_SYSTEM |
10 | #define TRACE_SYSTEM kvm | 11 | #define TRACE_SYSTEM kvm |
@@ -877,6 +878,42 @@ TRACE_EVENT(kvm_ple_window, | |||
877 | #define trace_kvm_ple_window_shrink(vcpu_id, new, old) \ | 878 | #define trace_kvm_ple_window_shrink(vcpu_id, new, old) \ |
878 | trace_kvm_ple_window(false, vcpu_id, new, old) | 879 | trace_kvm_ple_window(false, vcpu_id, new, old) |
879 | 880 | ||
881 | TRACE_EVENT(kvm_pvclock_update, | ||
882 | TP_PROTO(unsigned int vcpu_id, struct pvclock_vcpu_time_info *pvclock), | ||
883 | TP_ARGS(vcpu_id, pvclock), | ||
884 | |||
885 | TP_STRUCT__entry( | ||
886 | __field( unsigned int, vcpu_id ) | ||
887 | __field( __u32, version ) | ||
888 | __field( __u64, tsc_timestamp ) | ||
889 | __field( __u64, system_time ) | ||
890 | __field( __u32, tsc_to_system_mul ) | ||
891 | __field( __s8, tsc_shift ) | ||
892 | __field( __u8, flags ) | ||
893 | ), | ||
894 | |||
895 | TP_fast_assign( | ||
896 | __entry->vcpu_id = vcpu_id; | ||
897 | __entry->version = pvclock->version; | ||
898 | __entry->tsc_timestamp = pvclock->tsc_timestamp; | ||
899 | __entry->system_time = pvclock->system_time; | ||
900 | __entry->tsc_to_system_mul = pvclock->tsc_to_system_mul; | ||
901 | __entry->tsc_shift = pvclock->tsc_shift; | ||
902 | __entry->flags = pvclock->flags; | ||
903 | ), | ||
904 | |||
905 | TP_printk("vcpu_id %u, pvclock { version %u, tsc_timestamp 0x%llx, " | ||
906 | "system_time 0x%llx, tsc_to_system_mul 0x%x, tsc_shift %d, " | ||
907 | "flags 0x%x }", | ||
908 | __entry->vcpu_id, | ||
909 | __entry->version, | ||
910 | __entry->tsc_timestamp, | ||
911 | __entry->system_time, | ||
912 | __entry->tsc_to_system_mul, | ||
913 | __entry->tsc_shift, | ||
914 | __entry->flags) | ||
915 | ); | ||
916 | |||
880 | #endif /* _TRACE_KVM_H */ | 917 | #endif /* _TRACE_KVM_H */ |
881 | 918 | ||
882 | #undef TRACE_INCLUDE_PATH | 919 | #undef TRACE_INCLUDE_PATH |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 3e556c68351b..feb852b04598 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -99,13 +99,15 @@ module_param_named(enable_shadow_vmcs, enable_shadow_vmcs, bool, S_IRUGO); | |||
99 | static bool __read_mostly nested = 0; | 99 | static bool __read_mostly nested = 0; |
100 | module_param(nested, bool, S_IRUGO); | 100 | module_param(nested, bool, S_IRUGO); |
101 | 101 | ||
102 | static u64 __read_mostly host_xss; | ||
103 | |||
102 | #define KVM_GUEST_CR0_MASK (X86_CR0_NW | X86_CR0_CD) | 104 | #define KVM_GUEST_CR0_MASK (X86_CR0_NW | X86_CR0_CD) |
103 | #define KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST (X86_CR0_WP | X86_CR0_NE) | 105 | #define KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST (X86_CR0_WP | X86_CR0_NE) |
104 | #define KVM_VM_CR0_ALWAYS_ON \ | 106 | #define KVM_VM_CR0_ALWAYS_ON \ |
105 | (KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE) | 107 | (KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE) |
106 | #define KVM_CR4_GUEST_OWNED_BITS \ | 108 | #define KVM_CR4_GUEST_OWNED_BITS \ |
107 | (X86_CR4_PVI | X86_CR4_DE | X86_CR4_PCE | X86_CR4_OSFXSR \ | 109 | (X86_CR4_PVI | X86_CR4_DE | X86_CR4_PCE | X86_CR4_OSFXSR \ |
108 | | X86_CR4_OSXMMEXCPT) | 110 | | X86_CR4_OSXMMEXCPT | X86_CR4_TSD) |
109 | 111 | ||
110 | #define KVM_PMODE_VM_CR4_ALWAYS_ON (X86_CR4_PAE | X86_CR4_VMXE) | 112 | #define KVM_PMODE_VM_CR4_ALWAYS_ON (X86_CR4_PAE | X86_CR4_VMXE) |
111 | #define KVM_RMODE_VM_CR4_ALWAYS_ON (X86_CR4_VME | X86_CR4_PAE | X86_CR4_VMXE) | 113 | #define KVM_RMODE_VM_CR4_ALWAYS_ON (X86_CR4_VME | X86_CR4_PAE | X86_CR4_VMXE) |
@@ -214,6 +216,7 @@ struct __packed vmcs12 { | |||
214 | u64 virtual_apic_page_addr; | 216 | u64 virtual_apic_page_addr; |
215 | u64 apic_access_addr; | 217 | u64 apic_access_addr; |
216 | u64 ept_pointer; | 218 | u64 ept_pointer; |
219 | u64 xss_exit_bitmap; | ||
217 | u64 guest_physical_address; | 220 | u64 guest_physical_address; |
218 | u64 vmcs_link_pointer; | 221 | u64 vmcs_link_pointer; |
219 | u64 guest_ia32_debugctl; | 222 | u64 guest_ia32_debugctl; |
@@ -616,6 +619,7 @@ static const unsigned short vmcs_field_to_offset_table[] = { | |||
616 | FIELD64(VIRTUAL_APIC_PAGE_ADDR, virtual_apic_page_addr), | 619 | FIELD64(VIRTUAL_APIC_PAGE_ADDR, virtual_apic_page_addr), |
617 | FIELD64(APIC_ACCESS_ADDR, apic_access_addr), | 620 | FIELD64(APIC_ACCESS_ADDR, apic_access_addr), |
618 | FIELD64(EPT_POINTER, ept_pointer), | 621 | FIELD64(EPT_POINTER, ept_pointer), |
622 | FIELD64(XSS_EXIT_BITMAP, xss_exit_bitmap), | ||
619 | FIELD64(GUEST_PHYSICAL_ADDRESS, guest_physical_address), | 623 | FIELD64(GUEST_PHYSICAL_ADDRESS, guest_physical_address), |
620 | FIELD64(VMCS_LINK_POINTER, vmcs_link_pointer), | 624 | FIELD64(VMCS_LINK_POINTER, vmcs_link_pointer), |
621 | FIELD64(GUEST_IA32_DEBUGCTL, guest_ia32_debugctl), | 625 | FIELD64(GUEST_IA32_DEBUGCTL, guest_ia32_debugctl), |
@@ -720,12 +724,15 @@ static const unsigned short vmcs_field_to_offset_table[] = { | |||
720 | FIELD(HOST_RSP, host_rsp), | 724 | FIELD(HOST_RSP, host_rsp), |
721 | FIELD(HOST_RIP, host_rip), | 725 | FIELD(HOST_RIP, host_rip), |
722 | }; | 726 | }; |
723 | static const int max_vmcs_field = ARRAY_SIZE(vmcs_field_to_offset_table); | ||
724 | 727 | ||
725 | static inline short vmcs_field_to_offset(unsigned long field) | 728 | static inline short vmcs_field_to_offset(unsigned long field) |
726 | { | 729 | { |
727 | if (field >= max_vmcs_field || vmcs_field_to_offset_table[field] == 0) | 730 | BUILD_BUG_ON(ARRAY_SIZE(vmcs_field_to_offset_table) > SHRT_MAX); |
728 | return -1; | 731 | |
732 | if (field >= ARRAY_SIZE(vmcs_field_to_offset_table) || | ||
733 | vmcs_field_to_offset_table[field] == 0) | ||
734 | return -ENOENT; | ||
735 | |||
729 | return vmcs_field_to_offset_table[field]; | 736 | return vmcs_field_to_offset_table[field]; |
730 | } | 737 | } |
731 | 738 | ||
@@ -758,6 +765,7 @@ static u64 construct_eptp(unsigned long root_hpa); | |||
758 | static void kvm_cpu_vmxon(u64 addr); | 765 | static void kvm_cpu_vmxon(u64 addr); |
759 | static void kvm_cpu_vmxoff(void); | 766 | static void kvm_cpu_vmxoff(void); |
760 | static bool vmx_mpx_supported(void); | 767 | static bool vmx_mpx_supported(void); |
768 | static bool vmx_xsaves_supported(void); | ||
761 | static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr); | 769 | static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr); |
762 | static void vmx_set_segment(struct kvm_vcpu *vcpu, | 770 | static void vmx_set_segment(struct kvm_vcpu *vcpu, |
763 | struct kvm_segment *var, int seg); | 771 | struct kvm_segment *var, int seg); |
@@ -1098,6 +1106,12 @@ static inline int nested_cpu_has_ept(struct vmcs12 *vmcs12) | |||
1098 | return nested_cpu_has2(vmcs12, SECONDARY_EXEC_ENABLE_EPT); | 1106 | return nested_cpu_has2(vmcs12, SECONDARY_EXEC_ENABLE_EPT); |
1099 | } | 1107 | } |
1100 | 1108 | ||
1109 | static inline bool nested_cpu_has_xsaves(struct vmcs12 *vmcs12) | ||
1110 | { | ||
1111 | return nested_cpu_has2(vmcs12, SECONDARY_EXEC_XSAVES) && | ||
1112 | vmx_xsaves_supported(); | ||
1113 | } | ||
1114 | |||
1101 | static inline bool is_exception(u32 intr_info) | 1115 | static inline bool is_exception(u32 intr_info) |
1102 | { | 1116 | { |
1103 | return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK)) | 1117 | return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK)) |
@@ -1659,12 +1673,20 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset) | |||
1659 | vmx->guest_msrs[efer_offset].mask = ~ignore_bits; | 1673 | vmx->guest_msrs[efer_offset].mask = ~ignore_bits; |
1660 | 1674 | ||
1661 | clear_atomic_switch_msr(vmx, MSR_EFER); | 1675 | clear_atomic_switch_msr(vmx, MSR_EFER); |
1662 | /* On ept, can't emulate nx, and must switch nx atomically */ | 1676 | |
1663 | if (enable_ept && ((vmx->vcpu.arch.efer ^ host_efer) & EFER_NX)) { | 1677 | /* |
1678 | * On EPT, we can't emulate NX, so we must switch EFER atomically. | ||
1679 | * On CPUs that support "load IA32_EFER", always switch EFER | ||
1680 | * atomically, since it's faster than switching it manually. | ||
1681 | */ | ||
1682 | if (cpu_has_load_ia32_efer || | ||
1683 | (enable_ept && ((vmx->vcpu.arch.efer ^ host_efer) & EFER_NX))) { | ||
1664 | guest_efer = vmx->vcpu.arch.efer; | 1684 | guest_efer = vmx->vcpu.arch.efer; |
1665 | if (!(guest_efer & EFER_LMA)) | 1685 | if (!(guest_efer & EFER_LMA)) |
1666 | guest_efer &= ~EFER_LME; | 1686 | guest_efer &= ~EFER_LME; |
1667 | add_atomic_switch_msr(vmx, MSR_EFER, guest_efer, host_efer); | 1687 | if (guest_efer != host_efer) |
1688 | add_atomic_switch_msr(vmx, MSR_EFER, | ||
1689 | guest_efer, host_efer); | ||
1668 | return false; | 1690 | return false; |
1669 | } | 1691 | } |
1670 | 1692 | ||
@@ -2377,12 +2399,13 @@ static __init void nested_vmx_setup_ctls_msrs(void) | |||
2377 | nested_vmx_secondary_ctls_low = 0; | 2399 | nested_vmx_secondary_ctls_low = 0; |
2378 | nested_vmx_secondary_ctls_high &= | 2400 | nested_vmx_secondary_ctls_high &= |
2379 | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | | 2401 | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | |
2380 | SECONDARY_EXEC_UNRESTRICTED_GUEST | | 2402 | SECONDARY_EXEC_WBINVD_EXITING | |
2381 | SECONDARY_EXEC_WBINVD_EXITING; | 2403 | SECONDARY_EXEC_XSAVES; |
2382 | 2404 | ||
2383 | if (enable_ept) { | 2405 | if (enable_ept) { |
2384 | /* nested EPT: emulate EPT also to L1 */ | 2406 | /* nested EPT: emulate EPT also to L1 */ |
2385 | nested_vmx_secondary_ctls_high |= SECONDARY_EXEC_ENABLE_EPT; | 2407 | nested_vmx_secondary_ctls_high |= SECONDARY_EXEC_ENABLE_EPT | |
2408 | SECONDARY_EXEC_UNRESTRICTED_GUEST; | ||
2386 | nested_vmx_ept_caps = VMX_EPT_PAGE_WALK_4_BIT | | 2409 | nested_vmx_ept_caps = VMX_EPT_PAGE_WALK_4_BIT | |
2387 | VMX_EPTP_WB_BIT | VMX_EPT_2MB_PAGE_BIT | | 2410 | VMX_EPTP_WB_BIT | VMX_EPT_2MB_PAGE_BIT | |
2388 | VMX_EPT_INVEPT_BIT; | 2411 | VMX_EPT_INVEPT_BIT; |
@@ -2558,6 +2581,11 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) | |||
2558 | if (!nested_vmx_allowed(vcpu)) | 2581 | if (!nested_vmx_allowed(vcpu)) |
2559 | return 1; | 2582 | return 1; |
2560 | return vmx_get_vmx_msr(vcpu, msr_index, pdata); | 2583 | return vmx_get_vmx_msr(vcpu, msr_index, pdata); |
2584 | case MSR_IA32_XSS: | ||
2585 | if (!vmx_xsaves_supported()) | ||
2586 | return 1; | ||
2587 | data = vcpu->arch.ia32_xss; | ||
2588 | break; | ||
2561 | case MSR_TSC_AUX: | 2589 | case MSR_TSC_AUX: |
2562 | if (!to_vmx(vcpu)->rdtscp_enabled) | 2590 | if (!to_vmx(vcpu)->rdtscp_enabled) |
2563 | return 1; | 2591 | return 1; |
@@ -2649,6 +2677,22 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) | |||
2649 | break; | 2677 | break; |
2650 | case MSR_IA32_VMX_BASIC ... MSR_IA32_VMX_VMFUNC: | 2678 | case MSR_IA32_VMX_BASIC ... MSR_IA32_VMX_VMFUNC: |
2651 | return 1; /* they are read-only */ | 2679 | return 1; /* they are read-only */ |
2680 | case MSR_IA32_XSS: | ||
2681 | if (!vmx_xsaves_supported()) | ||
2682 | return 1; | ||
2683 | /* | ||
2684 | * The only supported bit as of Skylake is bit 8, but | ||
2685 | * it is not supported on KVM. | ||
2686 | */ | ||
2687 | if (data != 0) | ||
2688 | return 1; | ||
2689 | vcpu->arch.ia32_xss = data; | ||
2690 | if (vcpu->arch.ia32_xss != host_xss) | ||
2691 | add_atomic_switch_msr(vmx, MSR_IA32_XSS, | ||
2692 | vcpu->arch.ia32_xss, host_xss); | ||
2693 | else | ||
2694 | clear_atomic_switch_msr(vmx, MSR_IA32_XSS); | ||
2695 | break; | ||
2652 | case MSR_TSC_AUX: | 2696 | case MSR_TSC_AUX: |
2653 | if (!vmx->rdtscp_enabled) | 2697 | if (!vmx->rdtscp_enabled) |
2654 | return 1; | 2698 | return 1; |
@@ -2884,7 +2928,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) | |||
2884 | SECONDARY_EXEC_ENABLE_INVPCID | | 2928 | SECONDARY_EXEC_ENABLE_INVPCID | |
2885 | SECONDARY_EXEC_APIC_REGISTER_VIRT | | 2929 | SECONDARY_EXEC_APIC_REGISTER_VIRT | |
2886 | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | | 2930 | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | |
2887 | SECONDARY_EXEC_SHADOW_VMCS; | 2931 | SECONDARY_EXEC_SHADOW_VMCS | |
2932 | SECONDARY_EXEC_XSAVES; | ||
2888 | if (adjust_vmx_controls(min2, opt2, | 2933 | if (adjust_vmx_controls(min2, opt2, |
2889 | MSR_IA32_VMX_PROCBASED_CTLS2, | 2934 | MSR_IA32_VMX_PROCBASED_CTLS2, |
2890 | &_cpu_based_2nd_exec_control) < 0) | 2935 | &_cpu_based_2nd_exec_control) < 0) |
@@ -3007,6 +3052,9 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) | |||
3007 | } | 3052 | } |
3008 | } | 3053 | } |
3009 | 3054 | ||
3055 | if (cpu_has_xsaves) | ||
3056 | rdmsrl(MSR_IA32_XSS, host_xss); | ||
3057 | |||
3010 | return 0; | 3058 | return 0; |
3011 | } | 3059 | } |
3012 | 3060 | ||
@@ -3110,76 +3158,6 @@ static __init int alloc_kvm_area(void) | |||
3110 | return 0; | 3158 | return 0; |
3111 | } | 3159 | } |
3112 | 3160 | ||
3113 | static __init int hardware_setup(void) | ||
3114 | { | ||
3115 | if (setup_vmcs_config(&vmcs_config) < 0) | ||
3116 | return -EIO; | ||
3117 | |||
3118 | if (boot_cpu_has(X86_FEATURE_NX)) | ||
3119 | kvm_enable_efer_bits(EFER_NX); | ||
3120 | |||
3121 | if (!cpu_has_vmx_vpid()) | ||
3122 | enable_vpid = 0; | ||
3123 | if (!cpu_has_vmx_shadow_vmcs()) | ||
3124 | enable_shadow_vmcs = 0; | ||
3125 | if (enable_shadow_vmcs) | ||
3126 | init_vmcs_shadow_fields(); | ||
3127 | |||
3128 | if (!cpu_has_vmx_ept() || | ||
3129 | !cpu_has_vmx_ept_4levels()) { | ||
3130 | enable_ept = 0; | ||
3131 | enable_unrestricted_guest = 0; | ||
3132 | enable_ept_ad_bits = 0; | ||
3133 | } | ||
3134 | |||
3135 | if (!cpu_has_vmx_ept_ad_bits()) | ||
3136 | enable_ept_ad_bits = 0; | ||
3137 | |||
3138 | if (!cpu_has_vmx_unrestricted_guest()) | ||
3139 | enable_unrestricted_guest = 0; | ||
3140 | |||
3141 | if (!cpu_has_vmx_flexpriority()) { | ||
3142 | flexpriority_enabled = 0; | ||
3143 | |||
3144 | /* | ||
3145 | * set_apic_access_page_addr() is used to reload apic access | ||
3146 | * page upon invalidation. No need to do anything if the | ||
3147 | * processor does not have the APIC_ACCESS_ADDR VMCS field. | ||
3148 | */ | ||
3149 | kvm_x86_ops->set_apic_access_page_addr = NULL; | ||
3150 | } | ||
3151 | |||
3152 | if (!cpu_has_vmx_tpr_shadow()) | ||
3153 | kvm_x86_ops->update_cr8_intercept = NULL; | ||
3154 | |||
3155 | if (enable_ept && !cpu_has_vmx_ept_2m_page()) | ||
3156 | kvm_disable_largepages(); | ||
3157 | |||
3158 | if (!cpu_has_vmx_ple()) | ||
3159 | ple_gap = 0; | ||
3160 | |||
3161 | if (!cpu_has_vmx_apicv()) | ||
3162 | enable_apicv = 0; | ||
3163 | |||
3164 | if (enable_apicv) | ||
3165 | kvm_x86_ops->update_cr8_intercept = NULL; | ||
3166 | else { | ||
3167 | kvm_x86_ops->hwapic_irr_update = NULL; | ||
3168 | kvm_x86_ops->deliver_posted_interrupt = NULL; | ||
3169 | kvm_x86_ops->sync_pir_to_irr = vmx_sync_pir_to_irr_dummy; | ||
3170 | } | ||
3171 | |||
3172 | if (nested) | ||
3173 | nested_vmx_setup_ctls_msrs(); | ||
3174 | |||
3175 | return alloc_kvm_area(); | ||
3176 | } | ||
3177 | |||
3178 | static __exit void hardware_unsetup(void) | ||
3179 | { | ||
3180 | free_kvm_area(); | ||
3181 | } | ||
3182 | |||
3183 | static bool emulation_required(struct kvm_vcpu *vcpu) | 3161 | static bool emulation_required(struct kvm_vcpu *vcpu) |
3184 | { | 3162 | { |
3185 | return emulate_invalid_guest_state && !guest_state_valid(vcpu); | 3163 | return emulate_invalid_guest_state && !guest_state_valid(vcpu); |
@@ -4396,6 +4374,7 @@ static void ept_set_mmio_spte_mask(void) | |||
4396 | kvm_mmu_set_mmio_spte_mask((0x3ull << 62) | 0x6ull); | 4374 | kvm_mmu_set_mmio_spte_mask((0x3ull << 62) | 0x6ull); |
4397 | } | 4375 | } |
4398 | 4376 | ||
4377 | #define VMX_XSS_EXIT_BITMAP 0 | ||
4399 | /* | 4378 | /* |
4400 | * Sets up the vmcs for emulated real mode. | 4379 | * Sets up the vmcs for emulated real mode. |
4401 | */ | 4380 | */ |
@@ -4505,6 +4484,9 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) | |||
4505 | vmcs_writel(CR0_GUEST_HOST_MASK, ~0UL); | 4484 | vmcs_writel(CR0_GUEST_HOST_MASK, ~0UL); |
4506 | set_cr4_guest_host_mask(vmx); | 4485 | set_cr4_guest_host_mask(vmx); |
4507 | 4486 | ||
4487 | if (vmx_xsaves_supported()) | ||
4488 | vmcs_write64(XSS_EXIT_BITMAP, VMX_XSS_EXIT_BITMAP); | ||
4489 | |||
4508 | return 0; | 4490 | return 0; |
4509 | } | 4491 | } |
4510 | 4492 | ||
@@ -5163,13 +5145,20 @@ static int handle_cr(struct kvm_vcpu *vcpu) | |||
5163 | static int handle_dr(struct kvm_vcpu *vcpu) | 5145 | static int handle_dr(struct kvm_vcpu *vcpu) |
5164 | { | 5146 | { |
5165 | unsigned long exit_qualification; | 5147 | unsigned long exit_qualification; |
5166 | int dr, reg; | 5148 | int dr, dr7, reg; |
5149 | |||
5150 | exit_qualification = vmcs_readl(EXIT_QUALIFICATION); | ||
5151 | dr = exit_qualification & DEBUG_REG_ACCESS_NUM; | ||
5152 | |||
5153 | /* First, if DR does not exist, trigger UD */ | ||
5154 | if (!kvm_require_dr(vcpu, dr)) | ||
5155 | return 1; | ||
5167 | 5156 | ||
5168 | /* Do not handle if the CPL > 0, will trigger GP on re-entry */ | 5157 | /* Do not handle if the CPL > 0, will trigger GP on re-entry */ |
5169 | if (!kvm_require_cpl(vcpu, 0)) | 5158 | if (!kvm_require_cpl(vcpu, 0)) |
5170 | return 1; | 5159 | return 1; |
5171 | dr = vmcs_readl(GUEST_DR7); | 5160 | dr7 = vmcs_readl(GUEST_DR7); |
5172 | if (dr & DR7_GD) { | 5161 | if (dr7 & DR7_GD) { |
5173 | /* | 5162 | /* |
5174 | * As the vm-exit takes precedence over the debug trap, we | 5163 | * As the vm-exit takes precedence over the debug trap, we |
5175 | * need to emulate the latter, either for the host or the | 5164 | * need to emulate the latter, either for the host or the |
@@ -5177,17 +5166,14 @@ static int handle_dr(struct kvm_vcpu *vcpu) | |||
5177 | */ | 5166 | */ |
5178 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) { | 5167 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) { |
5179 | vcpu->run->debug.arch.dr6 = vcpu->arch.dr6; | 5168 | vcpu->run->debug.arch.dr6 = vcpu->arch.dr6; |
5180 | vcpu->run->debug.arch.dr7 = dr; | 5169 | vcpu->run->debug.arch.dr7 = dr7; |
5181 | vcpu->run->debug.arch.pc = | 5170 | vcpu->run->debug.arch.pc = kvm_get_linear_rip(vcpu); |
5182 | vmcs_readl(GUEST_CS_BASE) + | ||
5183 | vmcs_readl(GUEST_RIP); | ||
5184 | vcpu->run->debug.arch.exception = DB_VECTOR; | 5171 | vcpu->run->debug.arch.exception = DB_VECTOR; |
5185 | vcpu->run->exit_reason = KVM_EXIT_DEBUG; | 5172 | vcpu->run->exit_reason = KVM_EXIT_DEBUG; |
5186 | return 0; | 5173 | return 0; |
5187 | } else { | 5174 | } else { |
5188 | vcpu->arch.dr7 &= ~DR7_GD; | 5175 | vcpu->arch.dr6 &= ~15; |
5189 | vcpu->arch.dr6 |= DR6_BD | DR6_RTM; | 5176 | vcpu->arch.dr6 |= DR6_BD | DR6_RTM; |
5190 | vmcs_writel(GUEST_DR7, vcpu->arch.dr7); | ||
5191 | kvm_queue_exception(vcpu, DB_VECTOR); | 5177 | kvm_queue_exception(vcpu, DB_VECTOR); |
5192 | return 1; | 5178 | return 1; |
5193 | } | 5179 | } |
@@ -5209,8 +5195,6 @@ static int handle_dr(struct kvm_vcpu *vcpu) | |||
5209 | return 1; | 5195 | return 1; |
5210 | } | 5196 | } |
5211 | 5197 | ||
5212 | exit_qualification = vmcs_readl(EXIT_QUALIFICATION); | ||
5213 | dr = exit_qualification & DEBUG_REG_ACCESS_NUM; | ||
5214 | reg = DEBUG_REG_ACCESS_REG(exit_qualification); | 5198 | reg = DEBUG_REG_ACCESS_REG(exit_qualification); |
5215 | if (exit_qualification & TYPE_MOV_FROM_DR) { | 5199 | if (exit_qualification & TYPE_MOV_FROM_DR) { |
5216 | unsigned long val; | 5200 | unsigned long val; |
@@ -5391,6 +5375,20 @@ static int handle_xsetbv(struct kvm_vcpu *vcpu) | |||
5391 | return 1; | 5375 | return 1; |
5392 | } | 5376 | } |
5393 | 5377 | ||
5378 | static int handle_xsaves(struct kvm_vcpu *vcpu) | ||
5379 | { | ||
5380 | skip_emulated_instruction(vcpu); | ||
5381 | WARN(1, "this should never happen\n"); | ||
5382 | return 1; | ||
5383 | } | ||
5384 | |||
5385 | static int handle_xrstors(struct kvm_vcpu *vcpu) | ||
5386 | { | ||
5387 | skip_emulated_instruction(vcpu); | ||
5388 | WARN(1, "this should never happen\n"); | ||
5389 | return 1; | ||
5390 | } | ||
5391 | |||
5394 | static int handle_apic_access(struct kvm_vcpu *vcpu) | 5392 | static int handle_apic_access(struct kvm_vcpu *vcpu) |
5395 | { | 5393 | { |
5396 | if (likely(fasteoi)) { | 5394 | if (likely(fasteoi)) { |
@@ -5492,7 +5490,7 @@ static int handle_task_switch(struct kvm_vcpu *vcpu) | |||
5492 | } | 5490 | } |
5493 | 5491 | ||
5494 | /* clear all local breakpoint enable flags */ | 5492 | /* clear all local breakpoint enable flags */ |
5495 | vmcs_writel(GUEST_DR7, vmcs_readl(GUEST_DR7) & ~0x55); | 5493 | vmcs_writel(GUEST_DR7, vmcs_readl(GUEST_DR7) & ~0x155); |
5496 | 5494 | ||
5497 | /* | 5495 | /* |
5498 | * TODO: What about debug traps on tss switch? | 5496 | * TODO: What about debug traps on tss switch? |
@@ -5539,11 +5537,11 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu) | |||
5539 | trace_kvm_page_fault(gpa, exit_qualification); | 5537 | trace_kvm_page_fault(gpa, exit_qualification); |
5540 | 5538 | ||
5541 | /* It is a write fault? */ | 5539 | /* It is a write fault? */ |
5542 | error_code = exit_qualification & (1U << 1); | 5540 | error_code = exit_qualification & PFERR_WRITE_MASK; |
5543 | /* It is a fetch fault? */ | 5541 | /* It is a fetch fault? */ |
5544 | error_code |= (exit_qualification & (1U << 2)) << 2; | 5542 | error_code |= (exit_qualification << 2) & PFERR_FETCH_MASK; |
5545 | /* ept page table is present? */ | 5543 | /* ept page table is present? */ |
5546 | error_code |= (exit_qualification >> 3) & 0x1; | 5544 | error_code |= (exit_qualification >> 3) & PFERR_PRESENT_MASK; |
5547 | 5545 | ||
5548 | vcpu->arch.exit_qualification = exit_qualification; | 5546 | vcpu->arch.exit_qualification = exit_qualification; |
5549 | 5547 | ||
@@ -5785,6 +5783,204 @@ static void update_ple_window_actual_max(void) | |||
5785 | ple_window_grow, INT_MIN); | 5783 | ple_window_grow, INT_MIN); |
5786 | } | 5784 | } |
5787 | 5785 | ||
5786 | static __init int hardware_setup(void) | ||
5787 | { | ||
5788 | int r = -ENOMEM, i, msr; | ||
5789 | |||
5790 | rdmsrl_safe(MSR_EFER, &host_efer); | ||
5791 | |||
5792 | for (i = 0; i < ARRAY_SIZE(vmx_msr_index); ++i) | ||
5793 | kvm_define_shared_msr(i, vmx_msr_index[i]); | ||
5794 | |||
5795 | vmx_io_bitmap_a = (unsigned long *)__get_free_page(GFP_KERNEL); | ||
5796 | if (!vmx_io_bitmap_a) | ||
5797 | return r; | ||
5798 | |||
5799 | vmx_io_bitmap_b = (unsigned long *)__get_free_page(GFP_KERNEL); | ||
5800 | if (!vmx_io_bitmap_b) | ||
5801 | goto out; | ||
5802 | |||
5803 | vmx_msr_bitmap_legacy = (unsigned long *)__get_free_page(GFP_KERNEL); | ||
5804 | if (!vmx_msr_bitmap_legacy) | ||
5805 | goto out1; | ||
5806 | |||
5807 | vmx_msr_bitmap_legacy_x2apic = | ||
5808 | (unsigned long *)__get_free_page(GFP_KERNEL); | ||
5809 | if (!vmx_msr_bitmap_legacy_x2apic) | ||
5810 | goto out2; | ||
5811 | |||
5812 | vmx_msr_bitmap_longmode = (unsigned long *)__get_free_page(GFP_KERNEL); | ||
5813 | if (!vmx_msr_bitmap_longmode) | ||
5814 | goto out3; | ||
5815 | |||
5816 | vmx_msr_bitmap_longmode_x2apic = | ||
5817 | (unsigned long *)__get_free_page(GFP_KERNEL); | ||
5818 | if (!vmx_msr_bitmap_longmode_x2apic) | ||
5819 | goto out4; | ||
5820 | vmx_vmread_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL); | ||
5821 | if (!vmx_vmread_bitmap) | ||
5822 | goto out5; | ||
5823 | |||
5824 | vmx_vmwrite_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL); | ||
5825 | if (!vmx_vmwrite_bitmap) | ||
5826 | goto out6; | ||
5827 | |||
5828 | memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE); | ||
5829 | memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE); | ||
5830 | |||
5831 | /* | ||
5832 | * Allow direct access to the PC debug port (it is often used for I/O | ||
5833 | * delays, but the vmexits simply slow things down). | ||
5834 | */ | ||
5835 | memset(vmx_io_bitmap_a, 0xff, PAGE_SIZE); | ||
5836 | clear_bit(0x80, vmx_io_bitmap_a); | ||
5837 | |||
5838 | memset(vmx_io_bitmap_b, 0xff, PAGE_SIZE); | ||
5839 | |||
5840 | memset(vmx_msr_bitmap_legacy, 0xff, PAGE_SIZE); | ||
5841 | memset(vmx_msr_bitmap_longmode, 0xff, PAGE_SIZE); | ||
5842 | |||
5843 | vmx_disable_intercept_for_msr(MSR_FS_BASE, false); | ||
5844 | vmx_disable_intercept_for_msr(MSR_GS_BASE, false); | ||
5845 | vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true); | ||
5846 | vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false); | ||
5847 | vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false); | ||
5848 | vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false); | ||
5849 | vmx_disable_intercept_for_msr(MSR_IA32_BNDCFGS, true); | ||
5850 | |||
5851 | memcpy(vmx_msr_bitmap_legacy_x2apic, | ||
5852 | vmx_msr_bitmap_legacy, PAGE_SIZE); | ||
5853 | memcpy(vmx_msr_bitmap_longmode_x2apic, | ||
5854 | vmx_msr_bitmap_longmode, PAGE_SIZE); | ||
5855 | |||
5856 | if (enable_apicv) { | ||
5857 | for (msr = 0x800; msr <= 0x8ff; msr++) | ||
5858 | vmx_disable_intercept_msr_read_x2apic(msr); | ||
5859 | |||
5860 | /* According SDM, in x2apic mode, the whole id reg is used. | ||
5861 | * But in KVM, it only use the highest eight bits. Need to | ||
5862 | * intercept it */ | ||
5863 | vmx_enable_intercept_msr_read_x2apic(0x802); | ||
5864 | /* TMCCT */ | ||
5865 | vmx_enable_intercept_msr_read_x2apic(0x839); | ||
5866 | /* TPR */ | ||
5867 | vmx_disable_intercept_msr_write_x2apic(0x808); | ||
5868 | /* EOI */ | ||
5869 | vmx_disable_intercept_msr_write_x2apic(0x80b); | ||
5870 | /* SELF-IPI */ | ||
5871 | vmx_disable_intercept_msr_write_x2apic(0x83f); | ||
5872 | } | ||
5873 | |||
5874 | if (enable_ept) { | ||
5875 | kvm_mmu_set_mask_ptes(0ull, | ||
5876 | (enable_ept_ad_bits) ? VMX_EPT_ACCESS_BIT : 0ull, | ||
5877 | (enable_ept_ad_bits) ? VMX_EPT_DIRTY_BIT : 0ull, | ||
5878 | 0ull, VMX_EPT_EXECUTABLE_MASK); | ||
5879 | ept_set_mmio_spte_mask(); | ||
5880 | kvm_enable_tdp(); | ||
5881 | } else | ||
5882 | kvm_disable_tdp(); | ||
5883 | |||
5884 | update_ple_window_actual_max(); | ||
5885 | |||
5886 | if (setup_vmcs_config(&vmcs_config) < 0) { | ||
5887 | r = -EIO; | ||
5888 | goto out7; | ||
5889 | } | ||
5890 | |||
5891 | if (boot_cpu_has(X86_FEATURE_NX)) | ||
5892 | kvm_enable_efer_bits(EFER_NX); | ||
5893 | |||
5894 | if (!cpu_has_vmx_vpid()) | ||
5895 | enable_vpid = 0; | ||
5896 | if (!cpu_has_vmx_shadow_vmcs()) | ||
5897 | enable_shadow_vmcs = 0; | ||
5898 | if (enable_shadow_vmcs) | ||
5899 | init_vmcs_shadow_fields(); | ||
5900 | |||
5901 | if (!cpu_has_vmx_ept() || | ||
5902 | !cpu_has_vmx_ept_4levels()) { | ||
5903 | enable_ept = 0; | ||
5904 | enable_unrestricted_guest = 0; | ||
5905 | enable_ept_ad_bits = 0; | ||
5906 | } | ||
5907 | |||
5908 | if (!cpu_has_vmx_ept_ad_bits()) | ||
5909 | enable_ept_ad_bits = 0; | ||
5910 | |||
5911 | if (!cpu_has_vmx_unrestricted_guest()) | ||
5912 | enable_unrestricted_guest = 0; | ||
5913 | |||
5914 | if (!cpu_has_vmx_flexpriority()) { | ||
5915 | flexpriority_enabled = 0; | ||
5916 | |||
5917 | /* | ||
5918 | * set_apic_access_page_addr() is used to reload apic access | ||
5919 | * page upon invalidation. No need to do anything if the | ||
5920 | * processor does not have the APIC_ACCESS_ADDR VMCS field. | ||
5921 | */ | ||
5922 | kvm_x86_ops->set_apic_access_page_addr = NULL; | ||
5923 | } | ||
5924 | |||
5925 | if (!cpu_has_vmx_tpr_shadow()) | ||
5926 | kvm_x86_ops->update_cr8_intercept = NULL; | ||
5927 | |||
5928 | if (enable_ept && !cpu_has_vmx_ept_2m_page()) | ||
5929 | kvm_disable_largepages(); | ||
5930 | |||
5931 | if (!cpu_has_vmx_ple()) | ||
5932 | ple_gap = 0; | ||
5933 | |||
5934 | if (!cpu_has_vmx_apicv()) | ||
5935 | enable_apicv = 0; | ||
5936 | |||
5937 | if (enable_apicv) | ||
5938 | kvm_x86_ops->update_cr8_intercept = NULL; | ||
5939 | else { | ||
5940 | kvm_x86_ops->hwapic_irr_update = NULL; | ||
5941 | kvm_x86_ops->deliver_posted_interrupt = NULL; | ||
5942 | kvm_x86_ops->sync_pir_to_irr = vmx_sync_pir_to_irr_dummy; | ||
5943 | } | ||
5944 | |||
5945 | if (nested) | ||
5946 | nested_vmx_setup_ctls_msrs(); | ||
5947 | |||
5948 | return alloc_kvm_area(); | ||
5949 | |||
5950 | out7: | ||
5951 | free_page((unsigned long)vmx_vmwrite_bitmap); | ||
5952 | out6: | ||
5953 | free_page((unsigned long)vmx_vmread_bitmap); | ||
5954 | out5: | ||
5955 | free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic); | ||
5956 | out4: | ||
5957 | free_page((unsigned long)vmx_msr_bitmap_longmode); | ||
5958 | out3: | ||
5959 | free_page((unsigned long)vmx_msr_bitmap_legacy_x2apic); | ||
5960 | out2: | ||
5961 | free_page((unsigned long)vmx_msr_bitmap_legacy); | ||
5962 | out1: | ||
5963 | free_page((unsigned long)vmx_io_bitmap_b); | ||
5964 | out: | ||
5965 | free_page((unsigned long)vmx_io_bitmap_a); | ||
5966 | |||
5967 | return r; | ||
5968 | } | ||
5969 | |||
5970 | static __exit void hardware_unsetup(void) | ||
5971 | { | ||
5972 | free_page((unsigned long)vmx_msr_bitmap_legacy_x2apic); | ||
5973 | free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic); | ||
5974 | free_page((unsigned long)vmx_msr_bitmap_legacy); | ||
5975 | free_page((unsigned long)vmx_msr_bitmap_longmode); | ||
5976 | free_page((unsigned long)vmx_io_bitmap_b); | ||
5977 | free_page((unsigned long)vmx_io_bitmap_a); | ||
5978 | free_page((unsigned long)vmx_vmwrite_bitmap); | ||
5979 | free_page((unsigned long)vmx_vmread_bitmap); | ||
5980 | |||
5981 | free_kvm_area(); | ||
5982 | } | ||
5983 | |||
5788 | /* | 5984 | /* |
5789 | * Indicate a busy-waiting vcpu in spinlock. We do not enable the PAUSE | 5985 | * Indicate a busy-waiting vcpu in spinlock. We do not enable the PAUSE |
5790 | * exiting, so only get here on cpu with PAUSE-Loop-Exiting. | 5986 | * exiting, so only get here on cpu with PAUSE-Loop-Exiting. |
@@ -6361,58 +6557,60 @@ static inline int vmcs_field_readonly(unsigned long field) | |||
6361 | * some of the bits we return here (e.g., on 32-bit guests, only 32 bits of | 6557 | * some of the bits we return here (e.g., on 32-bit guests, only 32 bits of |
6362 | * 64-bit fields are to be returned). | 6558 | * 64-bit fields are to be returned). |
6363 | */ | 6559 | */ |
6364 | static inline bool vmcs12_read_any(struct kvm_vcpu *vcpu, | 6560 | static inline int vmcs12_read_any(struct kvm_vcpu *vcpu, |
6365 | unsigned long field, u64 *ret) | 6561 | unsigned long field, u64 *ret) |
6366 | { | 6562 | { |
6367 | short offset = vmcs_field_to_offset(field); | 6563 | short offset = vmcs_field_to_offset(field); |
6368 | char *p; | 6564 | char *p; |
6369 | 6565 | ||
6370 | if (offset < 0) | 6566 | if (offset < 0) |
6371 | return 0; | 6567 | return offset; |
6372 | 6568 | ||
6373 | p = ((char *)(get_vmcs12(vcpu))) + offset; | 6569 | p = ((char *)(get_vmcs12(vcpu))) + offset; |
6374 | 6570 | ||
6375 | switch (vmcs_field_type(field)) { | 6571 | switch (vmcs_field_type(field)) { |
6376 | case VMCS_FIELD_TYPE_NATURAL_WIDTH: | 6572 | case VMCS_FIELD_TYPE_NATURAL_WIDTH: |
6377 | *ret = *((natural_width *)p); | 6573 | *ret = *((natural_width *)p); |
6378 | return 1; | 6574 | return 0; |
6379 | case VMCS_FIELD_TYPE_U16: | 6575 | case VMCS_FIELD_TYPE_U16: |
6380 | *ret = *((u16 *)p); | 6576 | *ret = *((u16 *)p); |
6381 | return 1; | 6577 | return 0; |
6382 | case VMCS_FIELD_TYPE_U32: | 6578 | case VMCS_FIELD_TYPE_U32: |
6383 | *ret = *((u32 *)p); | 6579 | *ret = *((u32 *)p); |
6384 | return 1; | 6580 | return 0; |
6385 | case VMCS_FIELD_TYPE_U64: | 6581 | case VMCS_FIELD_TYPE_U64: |
6386 | *ret = *((u64 *)p); | 6582 | *ret = *((u64 *)p); |
6387 | return 1; | 6583 | return 0; |
6388 | default: | 6584 | default: |
6389 | return 0; /* can never happen. */ | 6585 | WARN_ON(1); |
6586 | return -ENOENT; | ||
6390 | } | 6587 | } |
6391 | } | 6588 | } |
6392 | 6589 | ||
6393 | 6590 | ||
6394 | static inline bool vmcs12_write_any(struct kvm_vcpu *vcpu, | 6591 | static inline int vmcs12_write_any(struct kvm_vcpu *vcpu, |
6395 | unsigned long field, u64 field_value){ | 6592 | unsigned long field, u64 field_value){ |
6396 | short offset = vmcs_field_to_offset(field); | 6593 | short offset = vmcs_field_to_offset(field); |
6397 | char *p = ((char *) get_vmcs12(vcpu)) + offset; | 6594 | char *p = ((char *) get_vmcs12(vcpu)) + offset; |
6398 | if (offset < 0) | 6595 | if (offset < 0) |
6399 | return false; | 6596 | return offset; |
6400 | 6597 | ||
6401 | switch (vmcs_field_type(field)) { | 6598 | switch (vmcs_field_type(field)) { |
6402 | case VMCS_FIELD_TYPE_U16: | 6599 | case VMCS_FIELD_TYPE_U16: |
6403 | *(u16 *)p = field_value; | 6600 | *(u16 *)p = field_value; |
6404 | return true; | 6601 | return 0; |
6405 | case VMCS_FIELD_TYPE_U32: | 6602 | case VMCS_FIELD_TYPE_U32: |
6406 | *(u32 *)p = field_value; | 6603 | *(u32 *)p = field_value; |
6407 | return true; | 6604 | return 0; |
6408 | case VMCS_FIELD_TYPE_U64: | 6605 | case VMCS_FIELD_TYPE_U64: |
6409 | *(u64 *)p = field_value; | 6606 | *(u64 *)p = field_value; |
6410 | return true; | 6607 | return 0; |
6411 | case VMCS_FIELD_TYPE_NATURAL_WIDTH: | 6608 | case VMCS_FIELD_TYPE_NATURAL_WIDTH: |
6412 | *(natural_width *)p = field_value; | 6609 | *(natural_width *)p = field_value; |
6413 | return true; | 6610 | return 0; |
6414 | default: | 6611 | default: |
6415 | return false; /* can never happen. */ | 6612 | WARN_ON(1); |
6613 | return -ENOENT; | ||
6416 | } | 6614 | } |
6417 | 6615 | ||
6418 | } | 6616 | } |
@@ -6445,6 +6643,9 @@ static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx) | |||
6445 | case VMCS_FIELD_TYPE_NATURAL_WIDTH: | 6643 | case VMCS_FIELD_TYPE_NATURAL_WIDTH: |
6446 | field_value = vmcs_readl(field); | 6644 | field_value = vmcs_readl(field); |
6447 | break; | 6645 | break; |
6646 | default: | ||
6647 | WARN_ON(1); | ||
6648 | continue; | ||
6448 | } | 6649 | } |
6449 | vmcs12_write_any(&vmx->vcpu, field, field_value); | 6650 | vmcs12_write_any(&vmx->vcpu, field, field_value); |
6450 | } | 6651 | } |
@@ -6490,6 +6691,9 @@ static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx) | |||
6490 | case VMCS_FIELD_TYPE_NATURAL_WIDTH: | 6691 | case VMCS_FIELD_TYPE_NATURAL_WIDTH: |
6491 | vmcs_writel(field, (long)field_value); | 6692 | vmcs_writel(field, (long)field_value); |
6492 | break; | 6693 | break; |
6694 | default: | ||
6695 | WARN_ON(1); | ||
6696 | break; | ||
6493 | } | 6697 | } |
6494 | } | 6698 | } |
6495 | } | 6699 | } |
@@ -6528,7 +6732,7 @@ static int handle_vmread(struct kvm_vcpu *vcpu) | |||
6528 | /* Decode instruction info and find the field to read */ | 6732 | /* Decode instruction info and find the field to read */ |
6529 | field = kvm_register_readl(vcpu, (((vmx_instruction_info) >> 28) & 0xf)); | 6733 | field = kvm_register_readl(vcpu, (((vmx_instruction_info) >> 28) & 0xf)); |
6530 | /* Read the field, zero-extended to a u64 field_value */ | 6734 | /* Read the field, zero-extended to a u64 field_value */ |
6531 | if (!vmcs12_read_any(vcpu, field, &field_value)) { | 6735 | if (vmcs12_read_any(vcpu, field, &field_value) < 0) { |
6532 | nested_vmx_failValid(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); | 6736 | nested_vmx_failValid(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); |
6533 | skip_emulated_instruction(vcpu); | 6737 | skip_emulated_instruction(vcpu); |
6534 | return 1; | 6738 | return 1; |
@@ -6598,7 +6802,7 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) | |||
6598 | return 1; | 6802 | return 1; |
6599 | } | 6803 | } |
6600 | 6804 | ||
6601 | if (!vmcs12_write_any(vcpu, field, field_value)) { | 6805 | if (vmcs12_write_any(vcpu, field, field_value) < 0) { |
6602 | nested_vmx_failValid(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); | 6806 | nested_vmx_failValid(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); |
6603 | skip_emulated_instruction(vcpu); | 6807 | skip_emulated_instruction(vcpu); |
6604 | return 1; | 6808 | return 1; |
@@ -6802,6 +7006,8 @@ static int (*const kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { | |||
6802 | [EXIT_REASON_MONITOR_INSTRUCTION] = handle_monitor, | 7006 | [EXIT_REASON_MONITOR_INSTRUCTION] = handle_monitor, |
6803 | [EXIT_REASON_INVEPT] = handle_invept, | 7007 | [EXIT_REASON_INVEPT] = handle_invept, |
6804 | [EXIT_REASON_INVVPID] = handle_invvpid, | 7008 | [EXIT_REASON_INVVPID] = handle_invvpid, |
7009 | [EXIT_REASON_XSAVES] = handle_xsaves, | ||
7010 | [EXIT_REASON_XRSTORS] = handle_xrstors, | ||
6805 | }; | 7011 | }; |
6806 | 7012 | ||
6807 | static const int kvm_vmx_max_exit_handlers = | 7013 | static const int kvm_vmx_max_exit_handlers = |
@@ -7089,6 +7295,14 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) | |||
7089 | return nested_cpu_has2(vmcs12, SECONDARY_EXEC_WBINVD_EXITING); | 7295 | return nested_cpu_has2(vmcs12, SECONDARY_EXEC_WBINVD_EXITING); |
7090 | case EXIT_REASON_XSETBV: | 7296 | case EXIT_REASON_XSETBV: |
7091 | return 1; | 7297 | return 1; |
7298 | case EXIT_REASON_XSAVES: case EXIT_REASON_XRSTORS: | ||
7299 | /* | ||
7300 | * This should never happen, since it is not possible to | ||
7301 | * set XSS to a non-zero value---neither in L1 nor in L2. | ||
7302 | * If if it were, XSS would have to be checked against | ||
7303 | * the XSS exit bitmap in vmcs12. | ||
7304 | */ | ||
7305 | return nested_cpu_has2(vmcs12, SECONDARY_EXEC_XSAVES); | ||
7092 | default: | 7306 | default: |
7093 | return 1; | 7307 | return 1; |
7094 | } | 7308 | } |
@@ -7277,6 +7491,9 @@ static void vmx_set_rvi(int vector) | |||
7277 | u16 status; | 7491 | u16 status; |
7278 | u8 old; | 7492 | u8 old; |
7279 | 7493 | ||
7494 | if (vector == -1) | ||
7495 | vector = 0; | ||
7496 | |||
7280 | status = vmcs_read16(GUEST_INTR_STATUS); | 7497 | status = vmcs_read16(GUEST_INTR_STATUS); |
7281 | old = (u8)status & 0xff; | 7498 | old = (u8)status & 0xff; |
7282 | if ((u8)vector != old) { | 7499 | if ((u8)vector != old) { |
@@ -7288,22 +7505,23 @@ static void vmx_set_rvi(int vector) | |||
7288 | 7505 | ||
7289 | static void vmx_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr) | 7506 | static void vmx_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr) |
7290 | { | 7507 | { |
7508 | if (!is_guest_mode(vcpu)) { | ||
7509 | vmx_set_rvi(max_irr); | ||
7510 | return; | ||
7511 | } | ||
7512 | |||
7291 | if (max_irr == -1) | 7513 | if (max_irr == -1) |
7292 | return; | 7514 | return; |
7293 | 7515 | ||
7294 | /* | 7516 | /* |
7295 | * If a vmexit is needed, vmx_check_nested_events handles it. | 7517 | * In guest mode. If a vmexit is needed, vmx_check_nested_events |
7518 | * handles it. | ||
7296 | */ | 7519 | */ |
7297 | if (is_guest_mode(vcpu) && nested_exit_on_intr(vcpu)) | 7520 | if (nested_exit_on_intr(vcpu)) |
7298 | return; | 7521 | return; |
7299 | 7522 | ||
7300 | if (!is_guest_mode(vcpu)) { | ||
7301 | vmx_set_rvi(max_irr); | ||
7302 | return; | ||
7303 | } | ||
7304 | |||
7305 | /* | 7523 | /* |
7306 | * Fall back to pre-APICv interrupt injection since L2 | 7524 | * Else, fall back to pre-APICv interrupt injection since L2 |
7307 | * is run without virtual interrupt delivery. | 7525 | * is run without virtual interrupt delivery. |
7308 | */ | 7526 | */ |
7309 | if (!kvm_event_needs_reinjection(vcpu) && | 7527 | if (!kvm_event_needs_reinjection(vcpu) && |
@@ -7400,6 +7618,12 @@ static bool vmx_mpx_supported(void) | |||
7400 | (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_BNDCFGS); | 7618 | (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_BNDCFGS); |
7401 | } | 7619 | } |
7402 | 7620 | ||
7621 | static bool vmx_xsaves_supported(void) | ||
7622 | { | ||
7623 | return vmcs_config.cpu_based_2nd_exec_ctrl & | ||
7624 | SECONDARY_EXEC_XSAVES; | ||
7625 | } | ||
7626 | |||
7403 | static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx) | 7627 | static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx) |
7404 | { | 7628 | { |
7405 | u32 exit_intr_info; | 7629 | u32 exit_intr_info; |
@@ -8135,6 +8359,8 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) | |||
8135 | vmcs_writel(GUEST_SYSENTER_ESP, vmcs12->guest_sysenter_esp); | 8359 | vmcs_writel(GUEST_SYSENTER_ESP, vmcs12->guest_sysenter_esp); |
8136 | vmcs_writel(GUEST_SYSENTER_EIP, vmcs12->guest_sysenter_eip); | 8360 | vmcs_writel(GUEST_SYSENTER_EIP, vmcs12->guest_sysenter_eip); |
8137 | 8361 | ||
8362 | if (nested_cpu_has_xsaves(vmcs12)) | ||
8363 | vmcs_write64(XSS_EXIT_BITMAP, vmcs12->xss_exit_bitmap); | ||
8138 | vmcs_write64(VMCS_LINK_POINTER, -1ull); | 8364 | vmcs_write64(VMCS_LINK_POINTER, -1ull); |
8139 | 8365 | ||
8140 | exec_control = vmcs12->pin_based_vm_exec_control; | 8366 | exec_control = vmcs12->pin_based_vm_exec_control; |
@@ -8775,6 +9001,8 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, | |||
8775 | vmcs12->guest_sysenter_eip = vmcs_readl(GUEST_SYSENTER_EIP); | 9001 | vmcs12->guest_sysenter_eip = vmcs_readl(GUEST_SYSENTER_EIP); |
8776 | if (vmx_mpx_supported()) | 9002 | if (vmx_mpx_supported()) |
8777 | vmcs12->guest_bndcfgs = vmcs_read64(GUEST_BNDCFGS); | 9003 | vmcs12->guest_bndcfgs = vmcs_read64(GUEST_BNDCFGS); |
9004 | if (nested_cpu_has_xsaves(vmcs12)) | ||
9005 | vmcs12->xss_exit_bitmap = vmcs_read64(XSS_EXIT_BITMAP); | ||
8778 | 9006 | ||
8779 | /* update exit information fields: */ | 9007 | /* update exit information fields: */ |
8780 | 9008 | ||
@@ -9176,6 +9404,7 @@ static struct kvm_x86_ops vmx_x86_ops = { | |||
9176 | .check_intercept = vmx_check_intercept, | 9404 | .check_intercept = vmx_check_intercept, |
9177 | .handle_external_intr = vmx_handle_external_intr, | 9405 | .handle_external_intr = vmx_handle_external_intr, |
9178 | .mpx_supported = vmx_mpx_supported, | 9406 | .mpx_supported = vmx_mpx_supported, |
9407 | .xsaves_supported = vmx_xsaves_supported, | ||
9179 | 9408 | ||
9180 | .check_nested_events = vmx_check_nested_events, | 9409 | .check_nested_events = vmx_check_nested_events, |
9181 | 9410 | ||
@@ -9184,150 +9413,21 @@ static struct kvm_x86_ops vmx_x86_ops = { | |||
9184 | 9413 | ||
9185 | static int __init vmx_init(void) | 9414 | static int __init vmx_init(void) |
9186 | { | 9415 | { |
9187 | int r, i, msr; | 9416 | int r = kvm_init(&vmx_x86_ops, sizeof(struct vcpu_vmx), |
9188 | 9417 | __alignof__(struct vcpu_vmx), THIS_MODULE); | |
9189 | rdmsrl_safe(MSR_EFER, &host_efer); | ||
9190 | |||
9191 | for (i = 0; i < ARRAY_SIZE(vmx_msr_index); ++i) | ||
9192 | kvm_define_shared_msr(i, vmx_msr_index[i]); | ||
9193 | |||
9194 | vmx_io_bitmap_a = (unsigned long *)__get_free_page(GFP_KERNEL); | ||
9195 | if (!vmx_io_bitmap_a) | ||
9196 | return -ENOMEM; | ||
9197 | |||
9198 | r = -ENOMEM; | ||
9199 | |||
9200 | vmx_io_bitmap_b = (unsigned long *)__get_free_page(GFP_KERNEL); | ||
9201 | if (!vmx_io_bitmap_b) | ||
9202 | goto out; | ||
9203 | |||
9204 | vmx_msr_bitmap_legacy = (unsigned long *)__get_free_page(GFP_KERNEL); | ||
9205 | if (!vmx_msr_bitmap_legacy) | ||
9206 | goto out1; | ||
9207 | |||
9208 | vmx_msr_bitmap_legacy_x2apic = | ||
9209 | (unsigned long *)__get_free_page(GFP_KERNEL); | ||
9210 | if (!vmx_msr_bitmap_legacy_x2apic) | ||
9211 | goto out2; | ||
9212 | |||
9213 | vmx_msr_bitmap_longmode = (unsigned long *)__get_free_page(GFP_KERNEL); | ||
9214 | if (!vmx_msr_bitmap_longmode) | ||
9215 | goto out3; | ||
9216 | |||
9217 | vmx_msr_bitmap_longmode_x2apic = | ||
9218 | (unsigned long *)__get_free_page(GFP_KERNEL); | ||
9219 | if (!vmx_msr_bitmap_longmode_x2apic) | ||
9220 | goto out4; | ||
9221 | vmx_vmread_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL); | ||
9222 | if (!vmx_vmread_bitmap) | ||
9223 | goto out5; | ||
9224 | |||
9225 | vmx_vmwrite_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL); | ||
9226 | if (!vmx_vmwrite_bitmap) | ||
9227 | goto out6; | ||
9228 | |||
9229 | memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE); | ||
9230 | memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE); | ||
9231 | |||
9232 | /* | ||
9233 | * Allow direct access to the PC debug port (it is often used for I/O | ||
9234 | * delays, but the vmexits simply slow things down). | ||
9235 | */ | ||
9236 | memset(vmx_io_bitmap_a, 0xff, PAGE_SIZE); | ||
9237 | clear_bit(0x80, vmx_io_bitmap_a); | ||
9238 | |||
9239 | memset(vmx_io_bitmap_b, 0xff, PAGE_SIZE); | ||
9240 | |||
9241 | memset(vmx_msr_bitmap_legacy, 0xff, PAGE_SIZE); | ||
9242 | memset(vmx_msr_bitmap_longmode, 0xff, PAGE_SIZE); | ||
9243 | |||
9244 | set_bit(0, vmx_vpid_bitmap); /* 0 is reserved for host */ | ||
9245 | |||
9246 | r = kvm_init(&vmx_x86_ops, sizeof(struct vcpu_vmx), | ||
9247 | __alignof__(struct vcpu_vmx), THIS_MODULE); | ||
9248 | if (r) | 9418 | if (r) |
9249 | goto out7; | 9419 | return r; |
9250 | 9420 | ||
9251 | #ifdef CONFIG_KEXEC | 9421 | #ifdef CONFIG_KEXEC |
9252 | rcu_assign_pointer(crash_vmclear_loaded_vmcss, | 9422 | rcu_assign_pointer(crash_vmclear_loaded_vmcss, |
9253 | crash_vmclear_local_loaded_vmcss); | 9423 | crash_vmclear_local_loaded_vmcss); |
9254 | #endif | 9424 | #endif |
9255 | 9425 | ||
9256 | vmx_disable_intercept_for_msr(MSR_FS_BASE, false); | ||
9257 | vmx_disable_intercept_for_msr(MSR_GS_BASE, false); | ||
9258 | vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true); | ||
9259 | vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false); | ||
9260 | vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false); | ||
9261 | vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false); | ||
9262 | vmx_disable_intercept_for_msr(MSR_IA32_BNDCFGS, true); | ||
9263 | |||
9264 | memcpy(vmx_msr_bitmap_legacy_x2apic, | ||
9265 | vmx_msr_bitmap_legacy, PAGE_SIZE); | ||
9266 | memcpy(vmx_msr_bitmap_longmode_x2apic, | ||
9267 | vmx_msr_bitmap_longmode, PAGE_SIZE); | ||
9268 | |||
9269 | if (enable_apicv) { | ||
9270 | for (msr = 0x800; msr <= 0x8ff; msr++) | ||
9271 | vmx_disable_intercept_msr_read_x2apic(msr); | ||
9272 | |||
9273 | /* According SDM, in x2apic mode, the whole id reg is used. | ||
9274 | * But in KVM, it only use the highest eight bits. Need to | ||
9275 | * intercept it */ | ||
9276 | vmx_enable_intercept_msr_read_x2apic(0x802); | ||
9277 | /* TMCCT */ | ||
9278 | vmx_enable_intercept_msr_read_x2apic(0x839); | ||
9279 | /* TPR */ | ||
9280 | vmx_disable_intercept_msr_write_x2apic(0x808); | ||
9281 | /* EOI */ | ||
9282 | vmx_disable_intercept_msr_write_x2apic(0x80b); | ||
9283 | /* SELF-IPI */ | ||
9284 | vmx_disable_intercept_msr_write_x2apic(0x83f); | ||
9285 | } | ||
9286 | |||
9287 | if (enable_ept) { | ||
9288 | kvm_mmu_set_mask_ptes(0ull, | ||
9289 | (enable_ept_ad_bits) ? VMX_EPT_ACCESS_BIT : 0ull, | ||
9290 | (enable_ept_ad_bits) ? VMX_EPT_DIRTY_BIT : 0ull, | ||
9291 | 0ull, VMX_EPT_EXECUTABLE_MASK); | ||
9292 | ept_set_mmio_spte_mask(); | ||
9293 | kvm_enable_tdp(); | ||
9294 | } else | ||
9295 | kvm_disable_tdp(); | ||
9296 | |||
9297 | update_ple_window_actual_max(); | ||
9298 | |||
9299 | return 0; | 9426 | return 0; |
9300 | |||
9301 | out7: | ||
9302 | free_page((unsigned long)vmx_vmwrite_bitmap); | ||
9303 | out6: | ||
9304 | free_page((unsigned long)vmx_vmread_bitmap); | ||
9305 | out5: | ||
9306 | free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic); | ||
9307 | out4: | ||
9308 | free_page((unsigned long)vmx_msr_bitmap_longmode); | ||
9309 | out3: | ||
9310 | free_page((unsigned long)vmx_msr_bitmap_legacy_x2apic); | ||
9311 | out2: | ||
9312 | free_page((unsigned long)vmx_msr_bitmap_legacy); | ||
9313 | out1: | ||
9314 | free_page((unsigned long)vmx_io_bitmap_b); | ||
9315 | out: | ||
9316 | free_page((unsigned long)vmx_io_bitmap_a); | ||
9317 | return r; | ||
9318 | } | 9427 | } |
9319 | 9428 | ||
9320 | static void __exit vmx_exit(void) | 9429 | static void __exit vmx_exit(void) |
9321 | { | 9430 | { |
9322 | free_page((unsigned long)vmx_msr_bitmap_legacy_x2apic); | ||
9323 | free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic); | ||
9324 | free_page((unsigned long)vmx_msr_bitmap_legacy); | ||
9325 | free_page((unsigned long)vmx_msr_bitmap_longmode); | ||
9326 | free_page((unsigned long)vmx_io_bitmap_b); | ||
9327 | free_page((unsigned long)vmx_io_bitmap_a); | ||
9328 | free_page((unsigned long)vmx_vmwrite_bitmap); | ||
9329 | free_page((unsigned long)vmx_vmread_bitmap); | ||
9330 | |||
9331 | #ifdef CONFIG_KEXEC | 9431 | #ifdef CONFIG_KEXEC |
9332 | RCU_INIT_POINTER(crash_vmclear_loaded_vmcss, NULL); | 9432 | RCU_INIT_POINTER(crash_vmclear_loaded_vmcss, NULL); |
9333 | synchronize_rcu(); | 9433 | synchronize_rcu(); |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 0033df32a745..c259814200bd 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "kvm_cache_regs.h" | 27 | #include "kvm_cache_regs.h" |
28 | #include "x86.h" | 28 | #include "x86.h" |
29 | #include "cpuid.h" | 29 | #include "cpuid.h" |
30 | #include "assigned-dev.h" | ||
30 | 31 | ||
31 | #include <linux/clocksource.h> | 32 | #include <linux/clocksource.h> |
32 | #include <linux/interrupt.h> | 33 | #include <linux/interrupt.h> |
@@ -353,6 +354,8 @@ static void kvm_multiple_exception(struct kvm_vcpu *vcpu, | |||
353 | 354 | ||
354 | if (!vcpu->arch.exception.pending) { | 355 | if (!vcpu->arch.exception.pending) { |
355 | queue: | 356 | queue: |
357 | if (has_error && !is_protmode(vcpu)) | ||
358 | has_error = false; | ||
356 | vcpu->arch.exception.pending = true; | 359 | vcpu->arch.exception.pending = true; |
357 | vcpu->arch.exception.has_error_code = has_error; | 360 | vcpu->arch.exception.has_error_code = has_error; |
358 | vcpu->arch.exception.nr = nr; | 361 | vcpu->arch.exception.nr = nr; |
@@ -455,6 +458,16 @@ bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl) | |||
455 | } | 458 | } |
456 | EXPORT_SYMBOL_GPL(kvm_require_cpl); | 459 | EXPORT_SYMBOL_GPL(kvm_require_cpl); |
457 | 460 | ||
461 | bool kvm_require_dr(struct kvm_vcpu *vcpu, int dr) | ||
462 | { | ||
463 | if ((dr != 4 && dr != 5) || !kvm_read_cr4_bits(vcpu, X86_CR4_DE)) | ||
464 | return true; | ||
465 | |||
466 | kvm_queue_exception(vcpu, UD_VECTOR); | ||
467 | return false; | ||
468 | } | ||
469 | EXPORT_SYMBOL_GPL(kvm_require_dr); | ||
470 | |||
458 | /* | 471 | /* |
459 | * This function will be used to read from the physical memory of the currently | 472 | * This function will be used to read from the physical memory of the currently |
460 | * running guest. The difference to kvm_read_guest_page is that this function | 473 | * running guest. The difference to kvm_read_guest_page is that this function |
@@ -656,6 +669,12 @@ int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) | |||
656 | if ((!(xcr0 & XSTATE_BNDREGS)) != (!(xcr0 & XSTATE_BNDCSR))) | 669 | if ((!(xcr0 & XSTATE_BNDREGS)) != (!(xcr0 & XSTATE_BNDCSR))) |
657 | return 1; | 670 | return 1; |
658 | 671 | ||
672 | if (xcr0 & XSTATE_AVX512) { | ||
673 | if (!(xcr0 & XSTATE_YMM)) | ||
674 | return 1; | ||
675 | if ((xcr0 & XSTATE_AVX512) != XSTATE_AVX512) | ||
676 | return 1; | ||
677 | } | ||
659 | kvm_put_guest_xcr0(vcpu); | 678 | kvm_put_guest_xcr0(vcpu); |
660 | vcpu->arch.xcr0 = xcr0; | 679 | vcpu->arch.xcr0 = xcr0; |
661 | 680 | ||
@@ -732,6 +751,10 @@ EXPORT_SYMBOL_GPL(kvm_set_cr4); | |||
732 | 751 | ||
733 | int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) | 752 | int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) |
734 | { | 753 | { |
754 | #ifdef CONFIG_X86_64 | ||
755 | cr3 &= ~CR3_PCID_INVD; | ||
756 | #endif | ||
757 | |||
735 | if (cr3 == kvm_read_cr3(vcpu) && !pdptrs_changed(vcpu)) { | 758 | if (cr3 == kvm_read_cr3(vcpu) && !pdptrs_changed(vcpu)) { |
736 | kvm_mmu_sync_roots(vcpu); | 759 | kvm_mmu_sync_roots(vcpu); |
737 | kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu); | 760 | kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu); |
@@ -811,8 +834,6 @@ static int __kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val) | |||
811 | vcpu->arch.eff_db[dr] = val; | 834 | vcpu->arch.eff_db[dr] = val; |
812 | break; | 835 | break; |
813 | case 4: | 836 | case 4: |
814 | if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) | ||
815 | return 1; /* #UD */ | ||
816 | /* fall through */ | 837 | /* fall through */ |
817 | case 6: | 838 | case 6: |
818 | if (val & 0xffffffff00000000ULL) | 839 | if (val & 0xffffffff00000000ULL) |
@@ -821,8 +842,6 @@ static int __kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val) | |||
821 | kvm_update_dr6(vcpu); | 842 | kvm_update_dr6(vcpu); |
822 | break; | 843 | break; |
823 | case 5: | 844 | case 5: |
824 | if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) | ||
825 | return 1; /* #UD */ | ||
826 | /* fall through */ | 845 | /* fall through */ |
827 | default: /* 7 */ | 846 | default: /* 7 */ |
828 | if (val & 0xffffffff00000000ULL) | 847 | if (val & 0xffffffff00000000ULL) |
@@ -837,27 +856,21 @@ static int __kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val) | |||
837 | 856 | ||
838 | int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val) | 857 | int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val) |
839 | { | 858 | { |
840 | int res; | 859 | if (__kvm_set_dr(vcpu, dr, val)) { |
841 | |||
842 | res = __kvm_set_dr(vcpu, dr, val); | ||
843 | if (res > 0) | ||
844 | kvm_queue_exception(vcpu, UD_VECTOR); | ||
845 | else if (res < 0) | ||
846 | kvm_inject_gp(vcpu, 0); | 860 | kvm_inject_gp(vcpu, 0); |
847 | 861 | return 1; | |
848 | return res; | 862 | } |
863 | return 0; | ||
849 | } | 864 | } |
850 | EXPORT_SYMBOL_GPL(kvm_set_dr); | 865 | EXPORT_SYMBOL_GPL(kvm_set_dr); |
851 | 866 | ||
852 | static int _kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val) | 867 | int kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val) |
853 | { | 868 | { |
854 | switch (dr) { | 869 | switch (dr) { |
855 | case 0 ... 3: | 870 | case 0 ... 3: |
856 | *val = vcpu->arch.db[dr]; | 871 | *val = vcpu->arch.db[dr]; |
857 | break; | 872 | break; |
858 | case 4: | 873 | case 4: |
859 | if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) | ||
860 | return 1; | ||
861 | /* fall through */ | 874 | /* fall through */ |
862 | case 6: | 875 | case 6: |
863 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) | 876 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) |
@@ -866,23 +879,11 @@ static int _kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val) | |||
866 | *val = kvm_x86_ops->get_dr6(vcpu); | 879 | *val = kvm_x86_ops->get_dr6(vcpu); |
867 | break; | 880 | break; |
868 | case 5: | 881 | case 5: |
869 | if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) | ||
870 | return 1; | ||
871 | /* fall through */ | 882 | /* fall through */ |
872 | default: /* 7 */ | 883 | default: /* 7 */ |
873 | *val = vcpu->arch.dr7; | 884 | *val = vcpu->arch.dr7; |
874 | break; | 885 | break; |
875 | } | 886 | } |
876 | |||
877 | return 0; | ||
878 | } | ||
879 | |||
880 | int kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val) | ||
881 | { | ||
882 | if (_kvm_get_dr(vcpu, dr, val)) { | ||
883 | kvm_queue_exception(vcpu, UD_VECTOR); | ||
884 | return 1; | ||
885 | } | ||
886 | return 0; | 887 | return 0; |
887 | } | 888 | } |
888 | EXPORT_SYMBOL_GPL(kvm_get_dr); | 889 | EXPORT_SYMBOL_GPL(kvm_get_dr); |
@@ -1237,21 +1238,22 @@ void kvm_track_tsc_matching(struct kvm_vcpu *vcpu) | |||
1237 | { | 1238 | { |
1238 | #ifdef CONFIG_X86_64 | 1239 | #ifdef CONFIG_X86_64 |
1239 | bool vcpus_matched; | 1240 | bool vcpus_matched; |
1240 | bool do_request = false; | ||
1241 | struct kvm_arch *ka = &vcpu->kvm->arch; | 1241 | struct kvm_arch *ka = &vcpu->kvm->arch; |
1242 | struct pvclock_gtod_data *gtod = &pvclock_gtod_data; | 1242 | struct pvclock_gtod_data *gtod = &pvclock_gtod_data; |
1243 | 1243 | ||
1244 | vcpus_matched = (ka->nr_vcpus_matched_tsc + 1 == | 1244 | vcpus_matched = (ka->nr_vcpus_matched_tsc + 1 == |
1245 | atomic_read(&vcpu->kvm->online_vcpus)); | 1245 | atomic_read(&vcpu->kvm->online_vcpus)); |
1246 | 1246 | ||
1247 | if (vcpus_matched && gtod->clock.vclock_mode == VCLOCK_TSC) | 1247 | /* |
1248 | if (!ka->use_master_clock) | 1248 | * Once the masterclock is enabled, always perform request in |
1249 | do_request = 1; | 1249 | * order to update it. |
1250 | 1250 | * | |
1251 | if (!vcpus_matched && ka->use_master_clock) | 1251 | * In order to enable masterclock, the host clocksource must be TSC |
1252 | do_request = 1; | 1252 | * and the vcpus need to have matched TSCs. When that happens, |
1253 | 1253 | * perform request to enable masterclock. | |
1254 | if (do_request) | 1254 | */ |
1255 | if (ka->use_master_clock || | ||
1256 | (gtod->clock.vclock_mode == VCLOCK_TSC && vcpus_matched)) | ||
1255 | kvm_make_request(KVM_REQ_MASTERCLOCK_UPDATE, vcpu); | 1257 | kvm_make_request(KVM_REQ_MASTERCLOCK_UPDATE, vcpu); |
1256 | 1258 | ||
1257 | trace_kvm_track_tsc(vcpu->vcpu_id, ka->nr_vcpus_matched_tsc, | 1259 | trace_kvm_track_tsc(vcpu->vcpu_id, ka->nr_vcpus_matched_tsc, |
@@ -1637,16 +1639,16 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) | |||
1637 | vcpu->hv_clock.system_time = kernel_ns + v->kvm->arch.kvmclock_offset; | 1639 | vcpu->hv_clock.system_time = kernel_ns + v->kvm->arch.kvmclock_offset; |
1638 | vcpu->last_guest_tsc = tsc_timestamp; | 1640 | vcpu->last_guest_tsc = tsc_timestamp; |
1639 | 1641 | ||
1642 | if (unlikely(kvm_read_guest_cached(v->kvm, &vcpu->pv_time, | ||
1643 | &guest_hv_clock, sizeof(guest_hv_clock)))) | ||
1644 | return 0; | ||
1645 | |||
1640 | /* | 1646 | /* |
1641 | * The interface expects us to write an even number signaling that the | 1647 | * The interface expects us to write an even number signaling that the |
1642 | * update is finished. Since the guest won't see the intermediate | 1648 | * update is finished. Since the guest won't see the intermediate |
1643 | * state, we just increase by 2 at the end. | 1649 | * state, we just increase by 2 at the end. |
1644 | */ | 1650 | */ |
1645 | vcpu->hv_clock.version += 2; | 1651 | vcpu->hv_clock.version = guest_hv_clock.version + 2; |
1646 | |||
1647 | if (unlikely(kvm_read_guest_cached(v->kvm, &vcpu->pv_time, | ||
1648 | &guest_hv_clock, sizeof(guest_hv_clock)))) | ||
1649 | return 0; | ||
1650 | 1652 | ||
1651 | /* retain PVCLOCK_GUEST_STOPPED if set in guest copy */ | 1653 | /* retain PVCLOCK_GUEST_STOPPED if set in guest copy */ |
1652 | pvclock_flags = (guest_hv_clock.flags & PVCLOCK_GUEST_STOPPED); | 1654 | pvclock_flags = (guest_hv_clock.flags & PVCLOCK_GUEST_STOPPED); |
@@ -1662,6 +1664,8 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) | |||
1662 | 1664 | ||
1663 | vcpu->hv_clock.flags = pvclock_flags; | 1665 | vcpu->hv_clock.flags = pvclock_flags; |
1664 | 1666 | ||
1667 | trace_kvm_pvclock_update(v->vcpu_id, &vcpu->hv_clock); | ||
1668 | |||
1665 | kvm_write_guest_cached(v->kvm, &vcpu->pv_time, | 1669 | kvm_write_guest_cached(v->kvm, &vcpu->pv_time, |
1666 | &vcpu->hv_clock, | 1670 | &vcpu->hv_clock, |
1667 | sizeof(vcpu->hv_clock)); | 1671 | sizeof(vcpu->hv_clock)); |
@@ -2140,7 +2144,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) | |||
2140 | case MSR_IA32_TSC_ADJUST: | 2144 | case MSR_IA32_TSC_ADJUST: |
2141 | if (guest_cpuid_has_tsc_adjust(vcpu)) { | 2145 | if (guest_cpuid_has_tsc_adjust(vcpu)) { |
2142 | if (!msr_info->host_initiated) { | 2146 | if (!msr_info->host_initiated) { |
2143 | u64 adj = data - vcpu->arch.ia32_tsc_adjust_msr; | 2147 | s64 adj = data - vcpu->arch.ia32_tsc_adjust_msr; |
2144 | kvm_x86_ops->adjust_tsc_offset(vcpu, adj, true); | 2148 | kvm_x86_ops->adjust_tsc_offset(vcpu, adj, true); |
2145 | } | 2149 | } |
2146 | vcpu->arch.ia32_tsc_adjust_msr = data; | 2150 | vcpu->arch.ia32_tsc_adjust_msr = data; |
@@ -3106,7 +3110,7 @@ static void kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu, | |||
3106 | unsigned long val; | 3110 | unsigned long val; |
3107 | 3111 | ||
3108 | memcpy(dbgregs->db, vcpu->arch.db, sizeof(vcpu->arch.db)); | 3112 | memcpy(dbgregs->db, vcpu->arch.db, sizeof(vcpu->arch.db)); |
3109 | _kvm_get_dr(vcpu, 6, &val); | 3113 | kvm_get_dr(vcpu, 6, &val); |
3110 | dbgregs->dr6 = val; | 3114 | dbgregs->dr6 = val; |
3111 | dbgregs->dr7 = vcpu->arch.dr7; | 3115 | dbgregs->dr7 = vcpu->arch.dr7; |
3112 | dbgregs->flags = 0; | 3116 | dbgregs->flags = 0; |
@@ -3128,15 +3132,89 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu, | |||
3128 | return 0; | 3132 | return 0; |
3129 | } | 3133 | } |
3130 | 3134 | ||
3135 | #define XSTATE_COMPACTION_ENABLED (1ULL << 63) | ||
3136 | |||
3137 | static void fill_xsave(u8 *dest, struct kvm_vcpu *vcpu) | ||
3138 | { | ||
3139 | struct xsave_struct *xsave = &vcpu->arch.guest_fpu.state->xsave; | ||
3140 | u64 xstate_bv = xsave->xsave_hdr.xstate_bv; | ||
3141 | u64 valid; | ||
3142 | |||
3143 | /* | ||
3144 | * Copy legacy XSAVE area, to avoid complications with CPUID | ||
3145 | * leaves 0 and 1 in the loop below. | ||
3146 | */ | ||
3147 | memcpy(dest, xsave, XSAVE_HDR_OFFSET); | ||
3148 | |||
3149 | /* Set XSTATE_BV */ | ||
3150 | *(u64 *)(dest + XSAVE_HDR_OFFSET) = xstate_bv; | ||
3151 | |||
3152 | /* | ||
3153 | * Copy each region from the possibly compacted offset to the | ||
3154 | * non-compacted offset. | ||
3155 | */ | ||
3156 | valid = xstate_bv & ~XSTATE_FPSSE; | ||
3157 | while (valid) { | ||
3158 | u64 feature = valid & -valid; | ||
3159 | int index = fls64(feature) - 1; | ||
3160 | void *src = get_xsave_addr(xsave, feature); | ||
3161 | |||
3162 | if (src) { | ||
3163 | u32 size, offset, ecx, edx; | ||
3164 | cpuid_count(XSTATE_CPUID, index, | ||
3165 | &size, &offset, &ecx, &edx); | ||
3166 | memcpy(dest + offset, src, size); | ||
3167 | } | ||
3168 | |||
3169 | valid -= feature; | ||
3170 | } | ||
3171 | } | ||
3172 | |||
3173 | static void load_xsave(struct kvm_vcpu *vcpu, u8 *src) | ||
3174 | { | ||
3175 | struct xsave_struct *xsave = &vcpu->arch.guest_fpu.state->xsave; | ||
3176 | u64 xstate_bv = *(u64 *)(src + XSAVE_HDR_OFFSET); | ||
3177 | u64 valid; | ||
3178 | |||
3179 | /* | ||
3180 | * Copy legacy XSAVE area, to avoid complications with CPUID | ||
3181 | * leaves 0 and 1 in the loop below. | ||
3182 | */ | ||
3183 | memcpy(xsave, src, XSAVE_HDR_OFFSET); | ||
3184 | |||
3185 | /* Set XSTATE_BV and possibly XCOMP_BV. */ | ||
3186 | xsave->xsave_hdr.xstate_bv = xstate_bv; | ||
3187 | if (cpu_has_xsaves) | ||
3188 | xsave->xsave_hdr.xcomp_bv = host_xcr0 | XSTATE_COMPACTION_ENABLED; | ||
3189 | |||
3190 | /* | ||
3191 | * Copy each region from the non-compacted offset to the | ||
3192 | * possibly compacted offset. | ||
3193 | */ | ||
3194 | valid = xstate_bv & ~XSTATE_FPSSE; | ||
3195 | while (valid) { | ||
3196 | u64 feature = valid & -valid; | ||
3197 | int index = fls64(feature) - 1; | ||
3198 | void *dest = get_xsave_addr(xsave, feature); | ||
3199 | |||
3200 | if (dest) { | ||
3201 | u32 size, offset, ecx, edx; | ||
3202 | cpuid_count(XSTATE_CPUID, index, | ||
3203 | &size, &offset, &ecx, &edx); | ||
3204 | memcpy(dest, src + offset, size); | ||
3205 | } else | ||
3206 | WARN_ON_ONCE(1); | ||
3207 | |||
3208 | valid -= feature; | ||
3209 | } | ||
3210 | } | ||
3211 | |||
3131 | static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu, | 3212 | static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu, |
3132 | struct kvm_xsave *guest_xsave) | 3213 | struct kvm_xsave *guest_xsave) |
3133 | { | 3214 | { |
3134 | if (cpu_has_xsave) { | 3215 | if (cpu_has_xsave) { |
3135 | memcpy(guest_xsave->region, | 3216 | memset(guest_xsave, 0, sizeof(struct kvm_xsave)); |
3136 | &vcpu->arch.guest_fpu.state->xsave, | 3217 | fill_xsave((u8 *) guest_xsave->region, vcpu); |
3137 | vcpu->arch.guest_xstate_size); | ||
3138 | *(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)] &= | ||
3139 | vcpu->arch.guest_supported_xcr0 | XSTATE_FPSSE; | ||
3140 | } else { | 3218 | } else { |
3141 | memcpy(guest_xsave->region, | 3219 | memcpy(guest_xsave->region, |
3142 | &vcpu->arch.guest_fpu.state->fxsave, | 3220 | &vcpu->arch.guest_fpu.state->fxsave, |
@@ -3160,8 +3238,7 @@ static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu, | |||
3160 | */ | 3238 | */ |
3161 | if (xstate_bv & ~kvm_supported_xcr0()) | 3239 | if (xstate_bv & ~kvm_supported_xcr0()) |
3162 | return -EINVAL; | 3240 | return -EINVAL; |
3163 | memcpy(&vcpu->arch.guest_fpu.state->xsave, | 3241 | load_xsave(vcpu, (u8 *)guest_xsave->region); |
3164 | guest_xsave->region, vcpu->arch.guest_xstate_size); | ||
3165 | } else { | 3242 | } else { |
3166 | if (xstate_bv & ~XSTATE_FPSSE) | 3243 | if (xstate_bv & ~XSTATE_FPSSE) |
3167 | return -EINVAL; | 3244 | return -EINVAL; |
@@ -4004,7 +4081,7 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
4004 | } | 4081 | } |
4005 | 4082 | ||
4006 | default: | 4083 | default: |
4007 | ; | 4084 | r = kvm_vm_ioctl_assigned_device(kvm, ioctl, arg); |
4008 | } | 4085 | } |
4009 | out: | 4086 | out: |
4010 | return r; | 4087 | return r; |
@@ -4667,7 +4744,7 @@ static void emulator_wbinvd(struct x86_emulate_ctxt *ctxt) | |||
4667 | 4744 | ||
4668 | int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long *dest) | 4745 | int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long *dest) |
4669 | { | 4746 | { |
4670 | return _kvm_get_dr(emul_to_vcpu(ctxt), dr, dest); | 4747 | return kvm_get_dr(emul_to_vcpu(ctxt), dr, dest); |
4671 | } | 4748 | } |
4672 | 4749 | ||
4673 | int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value) | 4750 | int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value) |
@@ -5211,21 +5288,17 @@ static void kvm_vcpu_check_singlestep(struct kvm_vcpu *vcpu, unsigned long rflag | |||
5211 | 5288 | ||
5212 | static bool kvm_vcpu_check_breakpoint(struct kvm_vcpu *vcpu, int *r) | 5289 | static bool kvm_vcpu_check_breakpoint(struct kvm_vcpu *vcpu, int *r) |
5213 | { | 5290 | { |
5214 | struct kvm_run *kvm_run = vcpu->run; | ||
5215 | unsigned long eip = vcpu->arch.emulate_ctxt.eip; | ||
5216 | u32 dr6 = 0; | ||
5217 | |||
5218 | if (unlikely(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) && | 5291 | if (unlikely(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) && |
5219 | (vcpu->arch.guest_debug_dr7 & DR7_BP_EN_MASK)) { | 5292 | (vcpu->arch.guest_debug_dr7 & DR7_BP_EN_MASK)) { |
5220 | dr6 = kvm_vcpu_check_hw_bp(eip, 0, | 5293 | struct kvm_run *kvm_run = vcpu->run; |
5294 | unsigned long eip = kvm_get_linear_rip(vcpu); | ||
5295 | u32 dr6 = kvm_vcpu_check_hw_bp(eip, 0, | ||
5221 | vcpu->arch.guest_debug_dr7, | 5296 | vcpu->arch.guest_debug_dr7, |
5222 | vcpu->arch.eff_db); | 5297 | vcpu->arch.eff_db); |
5223 | 5298 | ||
5224 | if (dr6 != 0) { | 5299 | if (dr6 != 0) { |
5225 | kvm_run->debug.arch.dr6 = dr6 | DR6_FIXED_1 | DR6_RTM; | 5300 | kvm_run->debug.arch.dr6 = dr6 | DR6_FIXED_1 | DR6_RTM; |
5226 | kvm_run->debug.arch.pc = kvm_rip_read(vcpu) + | 5301 | kvm_run->debug.arch.pc = eip; |
5227 | get_segment_base(vcpu, VCPU_SREG_CS); | ||
5228 | |||
5229 | kvm_run->debug.arch.exception = DB_VECTOR; | 5302 | kvm_run->debug.arch.exception = DB_VECTOR; |
5230 | kvm_run->exit_reason = KVM_EXIT_DEBUG; | 5303 | kvm_run->exit_reason = KVM_EXIT_DEBUG; |
5231 | *r = EMULATE_USER_EXIT; | 5304 | *r = EMULATE_USER_EXIT; |
@@ -5235,7 +5308,8 @@ static bool kvm_vcpu_check_breakpoint(struct kvm_vcpu *vcpu, int *r) | |||
5235 | 5308 | ||
5236 | if (unlikely(vcpu->arch.dr7 & DR7_BP_EN_MASK) && | 5309 | if (unlikely(vcpu->arch.dr7 & DR7_BP_EN_MASK) && |
5237 | !(kvm_get_rflags(vcpu) & X86_EFLAGS_RF)) { | 5310 | !(kvm_get_rflags(vcpu) & X86_EFLAGS_RF)) { |
5238 | dr6 = kvm_vcpu_check_hw_bp(eip, 0, | 5311 | unsigned long eip = kvm_get_linear_rip(vcpu); |
5312 | u32 dr6 = kvm_vcpu_check_hw_bp(eip, 0, | ||
5239 | vcpu->arch.dr7, | 5313 | vcpu->arch.dr7, |
5240 | vcpu->arch.db); | 5314 | vcpu->arch.db); |
5241 | 5315 | ||
@@ -5365,7 +5439,9 @@ restart: | |||
5365 | kvm_rip_write(vcpu, ctxt->eip); | 5439 | kvm_rip_write(vcpu, ctxt->eip); |
5366 | if (r == EMULATE_DONE) | 5440 | if (r == EMULATE_DONE) |
5367 | kvm_vcpu_check_singlestep(vcpu, rflags, &r); | 5441 | kvm_vcpu_check_singlestep(vcpu, rflags, &r); |
5368 | __kvm_set_rflags(vcpu, ctxt->eflags); | 5442 | if (!ctxt->have_exception || |
5443 | exception_type(ctxt->exception.vector) == EXCPT_TRAP) | ||
5444 | __kvm_set_rflags(vcpu, ctxt->eflags); | ||
5369 | 5445 | ||
5370 | /* | 5446 | /* |
5371 | * For STI, interrupts are shadowed; so KVM_REQ_EVENT will | 5447 | * For STI, interrupts are shadowed; so KVM_REQ_EVENT will |
@@ -5965,6 +6041,12 @@ static int inject_pending_event(struct kvm_vcpu *vcpu, bool req_int_win) | |||
5965 | __kvm_set_rflags(vcpu, kvm_get_rflags(vcpu) | | 6041 | __kvm_set_rflags(vcpu, kvm_get_rflags(vcpu) | |
5966 | X86_EFLAGS_RF); | 6042 | X86_EFLAGS_RF); |
5967 | 6043 | ||
6044 | if (vcpu->arch.exception.nr == DB_VECTOR && | ||
6045 | (vcpu->arch.dr7 & DR7_GD)) { | ||
6046 | vcpu->arch.dr7 &= ~DR7_GD; | ||
6047 | kvm_update_dr7(vcpu); | ||
6048 | } | ||
6049 | |||
5968 | kvm_x86_ops->queue_exception(vcpu, vcpu->arch.exception.nr, | 6050 | kvm_x86_ops->queue_exception(vcpu, vcpu->arch.exception.nr, |
5969 | vcpu->arch.exception.has_error_code, | 6051 | vcpu->arch.exception.has_error_code, |
5970 | vcpu->arch.exception.error_code, | 6052 | vcpu->arch.exception.error_code, |
@@ -6873,6 +6955,9 @@ int fx_init(struct kvm_vcpu *vcpu) | |||
6873 | return err; | 6955 | return err; |
6874 | 6956 | ||
6875 | fpu_finit(&vcpu->arch.guest_fpu); | 6957 | fpu_finit(&vcpu->arch.guest_fpu); |
6958 | if (cpu_has_xsaves) | ||
6959 | vcpu->arch.guest_fpu.state->xsave.xsave_hdr.xcomp_bv = | ||
6960 | host_xcr0 | XSTATE_COMPACTION_ENABLED; | ||
6876 | 6961 | ||
6877 | /* | 6962 | /* |
6878 | * Ensure guest xcr0 is valid for loading | 6963 | * Ensure guest xcr0 is valid for loading |
@@ -7024,7 +7109,7 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu) | |||
7024 | kvm_x86_ops->vcpu_reset(vcpu); | 7109 | kvm_x86_ops->vcpu_reset(vcpu); |
7025 | } | 7110 | } |
7026 | 7111 | ||
7027 | void kvm_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, unsigned int vector) | 7112 | void kvm_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector) |
7028 | { | 7113 | { |
7029 | struct kvm_segment cs; | 7114 | struct kvm_segment cs; |
7030 | 7115 | ||
@@ -7256,6 +7341,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | |||
7256 | if (type) | 7341 | if (type) |
7257 | return -EINVAL; | 7342 | return -EINVAL; |
7258 | 7343 | ||
7344 | INIT_HLIST_HEAD(&kvm->arch.mask_notifier_list); | ||
7259 | INIT_LIST_HEAD(&kvm->arch.active_mmu_pages); | 7345 | INIT_LIST_HEAD(&kvm->arch.active_mmu_pages); |
7260 | INIT_LIST_HEAD(&kvm->arch.zapped_obsolete_pages); | 7346 | INIT_LIST_HEAD(&kvm->arch.zapped_obsolete_pages); |
7261 | INIT_LIST_HEAD(&kvm->arch.assigned_dev_head); | 7347 | INIT_LIST_HEAD(&kvm->arch.assigned_dev_head); |
@@ -7536,12 +7622,18 @@ int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu) | |||
7536 | return kvm_x86_ops->interrupt_allowed(vcpu); | 7622 | return kvm_x86_ops->interrupt_allowed(vcpu); |
7537 | } | 7623 | } |
7538 | 7624 | ||
7539 | bool kvm_is_linear_rip(struct kvm_vcpu *vcpu, unsigned long linear_rip) | 7625 | unsigned long kvm_get_linear_rip(struct kvm_vcpu *vcpu) |
7540 | { | 7626 | { |
7541 | unsigned long current_rip = kvm_rip_read(vcpu) + | 7627 | if (is_64_bit_mode(vcpu)) |
7542 | get_segment_base(vcpu, VCPU_SREG_CS); | 7628 | return kvm_rip_read(vcpu); |
7629 | return (u32)(get_segment_base(vcpu, VCPU_SREG_CS) + | ||
7630 | kvm_rip_read(vcpu)); | ||
7631 | } | ||
7632 | EXPORT_SYMBOL_GPL(kvm_get_linear_rip); | ||
7543 | 7633 | ||
7544 | return current_rip == linear_rip; | 7634 | bool kvm_is_linear_rip(struct kvm_vcpu *vcpu, unsigned long linear_rip) |
7635 | { | ||
7636 | return kvm_get_linear_rip(vcpu) == linear_rip; | ||
7545 | } | 7637 | } |
7546 | EXPORT_SYMBOL_GPL(kvm_is_linear_rip); | 7638 | EXPORT_SYMBOL_GPL(kvm_is_linear_rip); |
7547 | 7639 | ||
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index 7cb9c45a5fe0..cc1d61af6140 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h | |||
@@ -162,7 +162,8 @@ int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt, | |||
162 | bool kvm_mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data); | 162 | bool kvm_mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data); |
163 | 163 | ||
164 | #define KVM_SUPPORTED_XCR0 (XSTATE_FP | XSTATE_SSE | XSTATE_YMM \ | 164 | #define KVM_SUPPORTED_XCR0 (XSTATE_FP | XSTATE_SSE | XSTATE_YMM \ |
165 | | XSTATE_BNDREGS | XSTATE_BNDCSR) | 165 | | XSTATE_BNDREGS | XSTATE_BNDCSR \ |
166 | | XSTATE_AVX512) | ||
166 | extern u64 host_xcr0; | 167 | extern u64 host_xcr0; |
167 | 168 | ||
168 | extern u64 kvm_supported_xcr0(void); | 169 | extern u64 kvm_supported_xcr0(void); |
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h index ad9db6045b2f..b3f45a578344 100644 --- a/include/kvm/arm_arch_timer.h +++ b/include/kvm/arm_arch_timer.h | |||
@@ -60,7 +60,8 @@ struct arch_timer_cpu { | |||
60 | 60 | ||
61 | #ifdef CONFIG_KVM_ARM_TIMER | 61 | #ifdef CONFIG_KVM_ARM_TIMER |
62 | int kvm_timer_hyp_init(void); | 62 | int kvm_timer_hyp_init(void); |
63 | int kvm_timer_init(struct kvm *kvm); | 63 | void kvm_timer_enable(struct kvm *kvm); |
64 | void kvm_timer_init(struct kvm *kvm); | ||
64 | void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu, | 65 | void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu, |
65 | const struct kvm_irq_level *irq); | 66 | const struct kvm_irq_level *irq); |
66 | void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu); | 67 | void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu); |
@@ -77,11 +78,8 @@ static inline int kvm_timer_hyp_init(void) | |||
77 | return 0; | 78 | return 0; |
78 | }; | 79 | }; |
79 | 80 | ||
80 | static inline int kvm_timer_init(struct kvm *kvm) | 81 | static inline void kvm_timer_enable(struct kvm *kvm) {} |
81 | { | 82 | static inline void kvm_timer_init(struct kvm *kvm) {} |
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static inline void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu, | 83 | static inline void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu, |
86 | const struct kvm_irq_level *irq) {} | 84 | const struct kvm_irq_level *irq) {} |
87 | static inline void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu) {} | 85 | static inline void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu) {} |
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 206dcc3b3f7a..ac4888dc86bc 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h | |||
@@ -274,7 +274,7 @@ struct kvm_exit_mmio; | |||
274 | #ifdef CONFIG_KVM_ARM_VGIC | 274 | #ifdef CONFIG_KVM_ARM_VGIC |
275 | int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write); | 275 | int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write); |
276 | int kvm_vgic_hyp_init(void); | 276 | int kvm_vgic_hyp_init(void); |
277 | int kvm_vgic_init(struct kvm *kvm); | 277 | int kvm_vgic_map_resources(struct kvm *kvm); |
278 | int kvm_vgic_create(struct kvm *kvm); | 278 | int kvm_vgic_create(struct kvm *kvm); |
279 | void kvm_vgic_destroy(struct kvm *kvm); | 279 | void kvm_vgic_destroy(struct kvm *kvm); |
280 | void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu); | 280 | void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu); |
@@ -287,7 +287,8 @@ bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run, | |||
287 | struct kvm_exit_mmio *mmio); | 287 | struct kvm_exit_mmio *mmio); |
288 | 288 | ||
289 | #define irqchip_in_kernel(k) (!!((k)->arch.vgic.in_kernel)) | 289 | #define irqchip_in_kernel(k) (!!((k)->arch.vgic.in_kernel)) |
290 | #define vgic_initialized(k) ((k)->arch.vgic.ready) | 290 | #define vgic_initialized(k) (!!((k)->arch.vgic.nr_cpus)) |
291 | #define vgic_ready(k) ((k)->arch.vgic.ready) | ||
291 | 292 | ||
292 | int vgic_v2_probe(struct device_node *vgic_node, | 293 | int vgic_v2_probe(struct device_node *vgic_node, |
293 | const struct vgic_ops **ops, | 294 | const struct vgic_ops **ops, |
@@ -321,7 +322,7 @@ static inline int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, | |||
321 | return -ENXIO; | 322 | return -ENXIO; |
322 | } | 323 | } |
323 | 324 | ||
324 | static inline int kvm_vgic_init(struct kvm *kvm) | 325 | static inline int kvm_vgic_map_resources(struct kvm *kvm) |
325 | { | 326 | { |
326 | return 0; | 327 | return 0; |
327 | } | 328 | } |
@@ -373,6 +374,11 @@ static inline bool vgic_initialized(struct kvm *kvm) | |||
373 | { | 374 | { |
374 | return true; | 375 | return true; |
375 | } | 376 | } |
377 | |||
378 | static inline bool vgic_ready(struct kvm *kvm) | ||
379 | { | ||
380 | return true; | ||
381 | } | ||
376 | #endif | 382 | #endif |
377 | 383 | ||
378 | #endif | 384 | #endif |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index a6059bdf7b03..26f106022c88 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
@@ -43,6 +43,7 @@ | |||
43 | * include/linux/kvm_h. | 43 | * include/linux/kvm_h. |
44 | */ | 44 | */ |
45 | #define KVM_MEMSLOT_INVALID (1UL << 16) | 45 | #define KVM_MEMSLOT_INVALID (1UL << 16) |
46 | #define KVM_MEMSLOT_INCOHERENT (1UL << 17) | ||
46 | 47 | ||
47 | /* Two fragments for cross MMIO pages. */ | 48 | /* Two fragments for cross MMIO pages. */ |
48 | #define KVM_MAX_MMIO_FRAGMENTS 2 | 49 | #define KVM_MAX_MMIO_FRAGMENTS 2 |
@@ -353,6 +354,8 @@ struct kvm_memslots { | |||
353 | struct kvm_memory_slot memslots[KVM_MEM_SLOTS_NUM]; | 354 | struct kvm_memory_slot memslots[KVM_MEM_SLOTS_NUM]; |
354 | /* The mapping table from slot id to the index in memslots[]. */ | 355 | /* The mapping table from slot id to the index in memslots[]. */ |
355 | short id_to_index[KVM_MEM_SLOTS_NUM]; | 356 | short id_to_index[KVM_MEM_SLOTS_NUM]; |
357 | atomic_t lru_slot; | ||
358 | int used_slots; | ||
356 | }; | 359 | }; |
357 | 360 | ||
358 | struct kvm { | 361 | struct kvm { |
@@ -395,7 +398,6 @@ struct kvm { | |||
395 | * Update side is protected by irq_lock. | 398 | * Update side is protected by irq_lock. |
396 | */ | 399 | */ |
397 | struct kvm_irq_routing_table __rcu *irq_routing; | 400 | struct kvm_irq_routing_table __rcu *irq_routing; |
398 | struct hlist_head mask_notifier_list; | ||
399 | #endif | 401 | #endif |
400 | #ifdef CONFIG_HAVE_KVM_IRQFD | 402 | #ifdef CONFIG_HAVE_KVM_IRQFD |
401 | struct hlist_head irq_ack_notifier_list; | 403 | struct hlist_head irq_ack_notifier_list; |
@@ -447,6 +449,14 @@ void kvm_vcpu_uninit(struct kvm_vcpu *vcpu); | |||
447 | int __must_check vcpu_load(struct kvm_vcpu *vcpu); | 449 | int __must_check vcpu_load(struct kvm_vcpu *vcpu); |
448 | void vcpu_put(struct kvm_vcpu *vcpu); | 450 | void vcpu_put(struct kvm_vcpu *vcpu); |
449 | 451 | ||
452 | #ifdef __KVM_HAVE_IOAPIC | ||
453 | void kvm_vcpu_request_scan_ioapic(struct kvm *kvm); | ||
454 | #else | ||
455 | static inline void kvm_vcpu_request_scan_ioapic(struct kvm *kvm) | ||
456 | { | ||
457 | } | ||
458 | #endif | ||
459 | |||
450 | #ifdef CONFIG_HAVE_KVM_IRQFD | 460 | #ifdef CONFIG_HAVE_KVM_IRQFD |
451 | int kvm_irqfd_init(void); | 461 | int kvm_irqfd_init(void); |
452 | void kvm_irqfd_exit(void); | 462 | void kvm_irqfd_exit(void); |
@@ -711,44 +721,6 @@ struct kvm_irq_ack_notifier { | |||
711 | void (*irq_acked)(struct kvm_irq_ack_notifier *kian); | 721 | void (*irq_acked)(struct kvm_irq_ack_notifier *kian); |
712 | }; | 722 | }; |
713 | 723 | ||
714 | struct kvm_assigned_dev_kernel { | ||
715 | struct kvm_irq_ack_notifier ack_notifier; | ||
716 | struct list_head list; | ||
717 | int assigned_dev_id; | ||
718 | int host_segnr; | ||
719 | int host_busnr; | ||
720 | int host_devfn; | ||
721 | unsigned int entries_nr; | ||
722 | int host_irq; | ||
723 | bool host_irq_disabled; | ||
724 | bool pci_2_3; | ||
725 | struct msix_entry *host_msix_entries; | ||
726 | int guest_irq; | ||
727 | struct msix_entry *guest_msix_entries; | ||
728 | unsigned long irq_requested_type; | ||
729 | int irq_source_id; | ||
730 | int flags; | ||
731 | struct pci_dev *dev; | ||
732 | struct kvm *kvm; | ||
733 | spinlock_t intx_lock; | ||
734 | spinlock_t intx_mask_lock; | ||
735 | char irq_name[32]; | ||
736 | struct pci_saved_state *pci_saved_state; | ||
737 | }; | ||
738 | |||
739 | struct kvm_irq_mask_notifier { | ||
740 | void (*func)(struct kvm_irq_mask_notifier *kimn, bool masked); | ||
741 | int irq; | ||
742 | struct hlist_node link; | ||
743 | }; | ||
744 | |||
745 | void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq, | ||
746 | struct kvm_irq_mask_notifier *kimn); | ||
747 | void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq, | ||
748 | struct kvm_irq_mask_notifier *kimn); | ||
749 | void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin, | ||
750 | bool mask); | ||
751 | |||
752 | int kvm_irq_map_gsi(struct kvm *kvm, | 724 | int kvm_irq_map_gsi(struct kvm *kvm, |
753 | struct kvm_kernel_irq_routing_entry *entries, int gsi); | 725 | struct kvm_kernel_irq_routing_entry *entries, int gsi); |
754 | int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin); | 726 | int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin); |
@@ -770,12 +742,6 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id); | |||
770 | #ifdef CONFIG_KVM_DEVICE_ASSIGNMENT | 742 | #ifdef CONFIG_KVM_DEVICE_ASSIGNMENT |
771 | int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot); | 743 | int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot); |
772 | void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot); | 744 | void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot); |
773 | int kvm_iommu_map_guest(struct kvm *kvm); | ||
774 | int kvm_iommu_unmap_guest(struct kvm *kvm); | ||
775 | int kvm_assign_device(struct kvm *kvm, | ||
776 | struct kvm_assigned_dev_kernel *assigned_dev); | ||
777 | int kvm_deassign_device(struct kvm *kvm, | ||
778 | struct kvm_assigned_dev_kernel *assigned_dev); | ||
779 | #else | 745 | #else |
780 | static inline int kvm_iommu_map_pages(struct kvm *kvm, | 746 | static inline int kvm_iommu_map_pages(struct kvm *kvm, |
781 | struct kvm_memory_slot *slot) | 747 | struct kvm_memory_slot *slot) |
@@ -787,11 +753,6 @@ static inline void kvm_iommu_unmap_pages(struct kvm *kvm, | |||
787 | struct kvm_memory_slot *slot) | 753 | struct kvm_memory_slot *slot) |
788 | { | 754 | { |
789 | } | 755 | } |
790 | |||
791 | static inline int kvm_iommu_unmap_guest(struct kvm *kvm) | ||
792 | { | ||
793 | return 0; | ||
794 | } | ||
795 | #endif | 756 | #endif |
796 | 757 | ||
797 | static inline void kvm_guest_enter(void) | 758 | static inline void kvm_guest_enter(void) |
@@ -832,12 +793,28 @@ static inline void kvm_guest_exit(void) | |||
832 | static inline struct kvm_memory_slot * | 793 | static inline struct kvm_memory_slot * |
833 | search_memslots(struct kvm_memslots *slots, gfn_t gfn) | 794 | search_memslots(struct kvm_memslots *slots, gfn_t gfn) |
834 | { | 795 | { |
835 | struct kvm_memory_slot *memslot; | 796 | int start = 0, end = slots->used_slots; |
797 | int slot = atomic_read(&slots->lru_slot); | ||
798 | struct kvm_memory_slot *memslots = slots->memslots; | ||
799 | |||
800 | if (gfn >= memslots[slot].base_gfn && | ||
801 | gfn < memslots[slot].base_gfn + memslots[slot].npages) | ||
802 | return &memslots[slot]; | ||
836 | 803 | ||
837 | kvm_for_each_memslot(memslot, slots) | 804 | while (start < end) { |
838 | if (gfn >= memslot->base_gfn && | 805 | slot = start + (end - start) / 2; |
839 | gfn < memslot->base_gfn + memslot->npages) | 806 | |
840 | return memslot; | 807 | if (gfn >= memslots[slot].base_gfn) |
808 | end = slot; | ||
809 | else | ||
810 | start = slot + 1; | ||
811 | } | ||
812 | |||
813 | if (gfn >= memslots[start].base_gfn && | ||
814 | gfn < memslots[start].base_gfn + memslots[start].npages) { | ||
815 | atomic_set(&slots->lru_slot, start); | ||
816 | return &memslots[start]; | ||
817 | } | ||
841 | 818 | ||
842 | return NULL; | 819 | return NULL; |
843 | } | 820 | } |
@@ -1011,25 +988,6 @@ static inline bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu) { return true; } | |||
1011 | 988 | ||
1012 | #endif | 989 | #endif |
1013 | 990 | ||
1014 | #ifdef CONFIG_KVM_DEVICE_ASSIGNMENT | ||
1015 | |||
1016 | long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl, | ||
1017 | unsigned long arg); | ||
1018 | |||
1019 | void kvm_free_all_assigned_devices(struct kvm *kvm); | ||
1020 | |||
1021 | #else | ||
1022 | |||
1023 | static inline long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl, | ||
1024 | unsigned long arg) | ||
1025 | { | ||
1026 | return -ENOTTY; | ||
1027 | } | ||
1028 | |||
1029 | static inline void kvm_free_all_assigned_devices(struct kvm *kvm) {} | ||
1030 | |||
1031 | #endif | ||
1032 | |||
1033 | static inline void kvm_make_request(int req, struct kvm_vcpu *vcpu) | 991 | static inline void kvm_make_request(int req, struct kvm_vcpu *vcpu) |
1034 | { | 992 | { |
1035 | set_bit(req, &vcpu->requests); | 993 | set_bit(req, &vcpu->requests); |
diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h index b606bb689a3e..931da7e917cf 100644 --- a/include/linux/kvm_types.h +++ b/include/linux/kvm_types.h | |||
@@ -54,33 +54,6 @@ typedef u64 hfn_t; | |||
54 | 54 | ||
55 | typedef hfn_t pfn_t; | 55 | typedef hfn_t pfn_t; |
56 | 56 | ||
57 | union kvm_ioapic_redirect_entry { | ||
58 | u64 bits; | ||
59 | struct { | ||
60 | u8 vector; | ||
61 | u8 delivery_mode:3; | ||
62 | u8 dest_mode:1; | ||
63 | u8 delivery_status:1; | ||
64 | u8 polarity:1; | ||
65 | u8 remote_irr:1; | ||
66 | u8 trig_mode:1; | ||
67 | u8 mask:1; | ||
68 | u8 reserve:7; | ||
69 | u8 reserved[4]; | ||
70 | u8 dest_id; | ||
71 | } fields; | ||
72 | }; | ||
73 | |||
74 | struct kvm_lapic_irq { | ||
75 | u32 vector; | ||
76 | u32 delivery_mode; | ||
77 | u32 dest_mode; | ||
78 | u32 level; | ||
79 | u32 trig_mode; | ||
80 | u32 shorthand; | ||
81 | u32 dest_id; | ||
82 | }; | ||
83 | |||
84 | struct gfn_to_hva_cache { | 57 | struct gfn_to_hva_cache { |
85 | u64 generation; | 58 | u64 generation; |
86 | gpa_t gpa; | 59 | gpa_t gpa; |
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 60768822b140..a37fd1224f36 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h | |||
@@ -647,11 +647,7 @@ struct kvm_ppc_smmu_info { | |||
647 | #define KVM_CAP_MP_STATE 14 | 647 | #define KVM_CAP_MP_STATE 14 |
648 | #define KVM_CAP_COALESCED_MMIO 15 | 648 | #define KVM_CAP_COALESCED_MMIO 15 |
649 | #define KVM_CAP_SYNC_MMU 16 /* Changes to host mmap are reflected in guest */ | 649 | #define KVM_CAP_SYNC_MMU 16 /* Changes to host mmap are reflected in guest */ |
650 | #define KVM_CAP_DEVICE_ASSIGNMENT 17 | ||
651 | #define KVM_CAP_IOMMU 18 | 650 | #define KVM_CAP_IOMMU 18 |
652 | #ifdef __KVM_HAVE_MSI | ||
653 | #define KVM_CAP_DEVICE_MSI 20 | ||
654 | #endif | ||
655 | /* Bug in KVM_SET_USER_MEMORY_REGION fixed: */ | 651 | /* Bug in KVM_SET_USER_MEMORY_REGION fixed: */ |
656 | #define KVM_CAP_DESTROY_MEMORY_REGION_WORKS 21 | 652 | #define KVM_CAP_DESTROY_MEMORY_REGION_WORKS 21 |
657 | #define KVM_CAP_USER_NMI 22 | 653 | #define KVM_CAP_USER_NMI 22 |
@@ -663,10 +659,6 @@ struct kvm_ppc_smmu_info { | |||
663 | #endif | 659 | #endif |
664 | #define KVM_CAP_IRQ_ROUTING 25 | 660 | #define KVM_CAP_IRQ_ROUTING 25 |
665 | #define KVM_CAP_IRQ_INJECT_STATUS 26 | 661 | #define KVM_CAP_IRQ_INJECT_STATUS 26 |
666 | #define KVM_CAP_DEVICE_DEASSIGNMENT 27 | ||
667 | #ifdef __KVM_HAVE_MSIX | ||
668 | #define KVM_CAP_DEVICE_MSIX 28 | ||
669 | #endif | ||
670 | #define KVM_CAP_ASSIGN_DEV_IRQ 29 | 662 | #define KVM_CAP_ASSIGN_DEV_IRQ 29 |
671 | /* Another bug in KVM_SET_USER_MEMORY_REGION fixed: */ | 663 | /* Another bug in KVM_SET_USER_MEMORY_REGION fixed: */ |
672 | #define KVM_CAP_JOIN_MEMORY_REGIONS_WORKS 30 | 664 | #define KVM_CAP_JOIN_MEMORY_REGIONS_WORKS 30 |
@@ -1107,9 +1099,6 @@ struct kvm_s390_ucas_mapping { | |||
1107 | #define KVM_X86_SETUP_MCE _IOW(KVMIO, 0x9c, __u64) | 1099 | #define KVM_X86_SETUP_MCE _IOW(KVMIO, 0x9c, __u64) |
1108 | #define KVM_X86_GET_MCE_CAP_SUPPORTED _IOR(KVMIO, 0x9d, __u64) | 1100 | #define KVM_X86_GET_MCE_CAP_SUPPORTED _IOR(KVMIO, 0x9d, __u64) |
1109 | #define KVM_X86_SET_MCE _IOW(KVMIO, 0x9e, struct kvm_x86_mce) | 1101 | #define KVM_X86_SET_MCE _IOW(KVMIO, 0x9e, struct kvm_x86_mce) |
1110 | /* IA64 stack access */ | ||
1111 | #define KVM_IA64_VCPU_GET_STACK _IOR(KVMIO, 0x9a, void *) | ||
1112 | #define KVM_IA64_VCPU_SET_STACK _IOW(KVMIO, 0x9b, void *) | ||
1113 | /* Available with KVM_CAP_VCPU_EVENTS */ | 1102 | /* Available with KVM_CAP_VCPU_EVENTS */ |
1114 | #define KVM_GET_VCPU_EVENTS _IOR(KVMIO, 0x9f, struct kvm_vcpu_events) | 1103 | #define KVM_GET_VCPU_EVENTS _IOR(KVMIO, 0x9f, struct kvm_vcpu_events) |
1115 | #define KVM_SET_VCPU_EVENTS _IOW(KVMIO, 0xa0, struct kvm_vcpu_events) | 1104 | #define KVM_SET_VCPU_EVENTS _IOW(KVMIO, 0xa0, struct kvm_vcpu_events) |
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c index 22fa819a9b6a..1c0772b340d8 100644 --- a/virt/kvm/arm/arch_timer.c +++ b/virt/kvm/arm/arch_timer.c | |||
@@ -61,12 +61,14 @@ static void timer_disarm(struct arch_timer_cpu *timer) | |||
61 | 61 | ||
62 | static void kvm_timer_inject_irq(struct kvm_vcpu *vcpu) | 62 | static void kvm_timer_inject_irq(struct kvm_vcpu *vcpu) |
63 | { | 63 | { |
64 | int ret; | ||
64 | struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; | 65 | struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; |
65 | 66 | ||
66 | timer->cntv_ctl |= ARCH_TIMER_CTRL_IT_MASK; | 67 | timer->cntv_ctl |= ARCH_TIMER_CTRL_IT_MASK; |
67 | kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id, | 68 | ret = kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id, |
68 | timer->irq->irq, | 69 | timer->irq->irq, |
69 | timer->irq->level); | 70 | timer->irq->level); |
71 | WARN_ON(ret); | ||
70 | } | 72 | } |
71 | 73 | ||
72 | static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id) | 74 | static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id) |
@@ -307,12 +309,24 @@ void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu) | |||
307 | timer_disarm(timer); | 309 | timer_disarm(timer); |
308 | } | 310 | } |
309 | 311 | ||
310 | int kvm_timer_init(struct kvm *kvm) | 312 | void kvm_timer_enable(struct kvm *kvm) |
311 | { | 313 | { |
312 | if (timecounter && wqueue) { | 314 | if (kvm->arch.timer.enabled) |
313 | kvm->arch.timer.cntvoff = kvm_phys_timer_read(); | 315 | return; |
316 | |||
317 | /* | ||
318 | * There is a potential race here between VCPUs starting for the first | ||
319 | * time, which may be enabling the timer multiple times. That doesn't | ||
320 | * hurt though, because we're just setting a variable to the same | ||
321 | * variable that it already was. The important thing is that all | ||
322 | * VCPUs have the enabled variable set, before entering the guest, if | ||
323 | * the arch timers are enabled. | ||
324 | */ | ||
325 | if (timecounter && wqueue) | ||
314 | kvm->arch.timer.enabled = 1; | 326 | kvm->arch.timer.enabled = 1; |
315 | } | 327 | } |
316 | 328 | ||
317 | return 0; | 329 | void kvm_timer_init(struct kvm *kvm) |
330 | { | ||
331 | kvm->arch.timer.cntvoff = kvm_phys_timer_read(); | ||
318 | } | 332 | } |
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index aacdb59f30de..03affc7bf453 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c | |||
@@ -91,6 +91,7 @@ | |||
91 | #define ACCESS_WRITE_VALUE (3 << 1) | 91 | #define ACCESS_WRITE_VALUE (3 << 1) |
92 | #define ACCESS_WRITE_MASK(x) ((x) & (3 << 1)) | 92 | #define ACCESS_WRITE_MASK(x) ((x) & (3 << 1)) |
93 | 93 | ||
94 | static int vgic_init(struct kvm *kvm); | ||
94 | static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu); | 95 | static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu); |
95 | static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu); | 96 | static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu); |
96 | static void vgic_update_state(struct kvm *kvm); | 97 | static void vgic_update_state(struct kvm *kvm); |
@@ -1607,7 +1608,7 @@ static int vgic_validate_injection(struct kvm_vcpu *vcpu, int irq, int level) | |||
1607 | } | 1608 | } |
1608 | } | 1609 | } |
1609 | 1610 | ||
1610 | static bool vgic_update_irq_pending(struct kvm *kvm, int cpuid, | 1611 | static int vgic_update_irq_pending(struct kvm *kvm, int cpuid, |
1611 | unsigned int irq_num, bool level) | 1612 | unsigned int irq_num, bool level) |
1612 | { | 1613 | { |
1613 | struct vgic_dist *dist = &kvm->arch.vgic; | 1614 | struct vgic_dist *dist = &kvm->arch.vgic; |
@@ -1643,9 +1644,10 @@ static bool vgic_update_irq_pending(struct kvm *kvm, int cpuid, | |||
1643 | vgic_dist_irq_clear_level(vcpu, irq_num); | 1644 | vgic_dist_irq_clear_level(vcpu, irq_num); |
1644 | if (!vgic_dist_irq_soft_pend(vcpu, irq_num)) | 1645 | if (!vgic_dist_irq_soft_pend(vcpu, irq_num)) |
1645 | vgic_dist_irq_clear_pending(vcpu, irq_num); | 1646 | vgic_dist_irq_clear_pending(vcpu, irq_num); |
1646 | } else { | ||
1647 | vgic_dist_irq_clear_pending(vcpu, irq_num); | ||
1648 | } | 1647 | } |
1648 | |||
1649 | ret = false; | ||
1650 | goto out; | ||
1649 | } | 1651 | } |
1650 | 1652 | ||
1651 | enabled = vgic_irq_is_enabled(vcpu, irq_num); | 1653 | enabled = vgic_irq_is_enabled(vcpu, irq_num); |
@@ -1672,7 +1674,7 @@ static bool vgic_update_irq_pending(struct kvm *kvm, int cpuid, | |||
1672 | out: | 1674 | out: |
1673 | spin_unlock(&dist->lock); | 1675 | spin_unlock(&dist->lock); |
1674 | 1676 | ||
1675 | return ret; | 1677 | return ret ? cpuid : -EINVAL; |
1676 | } | 1678 | } |
1677 | 1679 | ||
1678 | /** | 1680 | /** |
@@ -1692,11 +1694,26 @@ out: | |||
1692 | int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num, | 1694 | int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num, |
1693 | bool level) | 1695 | bool level) |
1694 | { | 1696 | { |
1695 | if (likely(vgic_initialized(kvm)) && | 1697 | int ret = 0; |
1696 | vgic_update_irq_pending(kvm, cpuid, irq_num, level)) | 1698 | int vcpu_id; |
1697 | vgic_kick_vcpus(kvm); | ||
1698 | 1699 | ||
1699 | return 0; | 1700 | if (unlikely(!vgic_initialized(kvm))) { |
1701 | mutex_lock(&kvm->lock); | ||
1702 | ret = vgic_init(kvm); | ||
1703 | mutex_unlock(&kvm->lock); | ||
1704 | |||
1705 | if (ret) | ||
1706 | goto out; | ||
1707 | } | ||
1708 | |||
1709 | vcpu_id = vgic_update_irq_pending(kvm, cpuid, irq_num, level); | ||
1710 | if (vcpu_id >= 0) { | ||
1711 | /* kick the specified vcpu */ | ||
1712 | kvm_vcpu_kick(kvm_get_vcpu(kvm, vcpu_id)); | ||
1713 | } | ||
1714 | |||
1715 | out: | ||
1716 | return ret; | ||
1700 | } | 1717 | } |
1701 | 1718 | ||
1702 | static irqreturn_t vgic_maintenance_handler(int irq, void *data) | 1719 | static irqreturn_t vgic_maintenance_handler(int irq, void *data) |
@@ -1726,39 +1743,14 @@ static int vgic_vcpu_init_maps(struct kvm_vcpu *vcpu, int nr_irqs) | |||
1726 | 1743 | ||
1727 | int sz = (nr_irqs - VGIC_NR_PRIVATE_IRQS) / 8; | 1744 | int sz = (nr_irqs - VGIC_NR_PRIVATE_IRQS) / 8; |
1728 | vgic_cpu->pending_shared = kzalloc(sz, GFP_KERNEL); | 1745 | vgic_cpu->pending_shared = kzalloc(sz, GFP_KERNEL); |
1729 | vgic_cpu->vgic_irq_lr_map = kzalloc(nr_irqs, GFP_KERNEL); | 1746 | vgic_cpu->vgic_irq_lr_map = kmalloc(nr_irqs, GFP_KERNEL); |
1730 | 1747 | ||
1731 | if (!vgic_cpu->pending_shared || !vgic_cpu->vgic_irq_lr_map) { | 1748 | if (!vgic_cpu->pending_shared || !vgic_cpu->vgic_irq_lr_map) { |
1732 | kvm_vgic_vcpu_destroy(vcpu); | 1749 | kvm_vgic_vcpu_destroy(vcpu); |
1733 | return -ENOMEM; | 1750 | return -ENOMEM; |
1734 | } | 1751 | } |
1735 | 1752 | ||
1736 | return 0; | 1753 | memset(vgic_cpu->vgic_irq_lr_map, LR_EMPTY, nr_irqs); |
1737 | } | ||
1738 | |||
1739 | /** | ||
1740 | * kvm_vgic_vcpu_init - Initialize per-vcpu VGIC state | ||
1741 | * @vcpu: pointer to the vcpu struct | ||
1742 | * | ||
1743 | * Initialize the vgic_cpu struct and vgic_dist struct fields pertaining to | ||
1744 | * this vcpu and enable the VGIC for this VCPU | ||
1745 | */ | ||
1746 | static void kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) | ||
1747 | { | ||
1748 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; | ||
1749 | struct vgic_dist *dist = &vcpu->kvm->arch.vgic; | ||
1750 | int i; | ||
1751 | |||
1752 | for (i = 0; i < dist->nr_irqs; i++) { | ||
1753 | if (i < VGIC_NR_PPIS) | ||
1754 | vgic_bitmap_set_irq_val(&dist->irq_enabled, | ||
1755 | vcpu->vcpu_id, i, 1); | ||
1756 | if (i < VGIC_NR_PRIVATE_IRQS) | ||
1757 | vgic_bitmap_set_irq_val(&dist->irq_cfg, | ||
1758 | vcpu->vcpu_id, i, VGIC_CFG_EDGE); | ||
1759 | |||
1760 | vgic_cpu->vgic_irq_lr_map[i] = LR_EMPTY; | ||
1761 | } | ||
1762 | 1754 | ||
1763 | /* | 1755 | /* |
1764 | * Store the number of LRs per vcpu, so we don't have to go | 1756 | * Store the number of LRs per vcpu, so we don't have to go |
@@ -1767,7 +1759,7 @@ static void kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) | |||
1767 | */ | 1759 | */ |
1768 | vgic_cpu->nr_lr = vgic->nr_lr; | 1760 | vgic_cpu->nr_lr = vgic->nr_lr; |
1769 | 1761 | ||
1770 | vgic_enable(vcpu); | 1762 | return 0; |
1771 | } | 1763 | } |
1772 | 1764 | ||
1773 | void kvm_vgic_destroy(struct kvm *kvm) | 1765 | void kvm_vgic_destroy(struct kvm *kvm) |
@@ -1798,20 +1790,21 @@ void kvm_vgic_destroy(struct kvm *kvm) | |||
1798 | dist->irq_spi_cpu = NULL; | 1790 | dist->irq_spi_cpu = NULL; |
1799 | dist->irq_spi_target = NULL; | 1791 | dist->irq_spi_target = NULL; |
1800 | dist->irq_pending_on_cpu = NULL; | 1792 | dist->irq_pending_on_cpu = NULL; |
1793 | dist->nr_cpus = 0; | ||
1801 | } | 1794 | } |
1802 | 1795 | ||
1803 | /* | 1796 | /* |
1804 | * Allocate and initialize the various data structures. Must be called | 1797 | * Allocate and initialize the various data structures. Must be called |
1805 | * with kvm->lock held! | 1798 | * with kvm->lock held! |
1806 | */ | 1799 | */ |
1807 | static int vgic_init_maps(struct kvm *kvm) | 1800 | static int vgic_init(struct kvm *kvm) |
1808 | { | 1801 | { |
1809 | struct vgic_dist *dist = &kvm->arch.vgic; | 1802 | struct vgic_dist *dist = &kvm->arch.vgic; |
1810 | struct kvm_vcpu *vcpu; | 1803 | struct kvm_vcpu *vcpu; |
1811 | int nr_cpus, nr_irqs; | 1804 | int nr_cpus, nr_irqs; |
1812 | int ret, i; | 1805 | int ret, i, vcpu_id; |
1813 | 1806 | ||
1814 | if (dist->nr_cpus) /* Already allocated */ | 1807 | if (vgic_initialized(kvm)) |
1815 | return 0; | 1808 | return 0; |
1816 | 1809 | ||
1817 | nr_cpus = dist->nr_cpus = atomic_read(&kvm->online_vcpus); | 1810 | nr_cpus = dist->nr_cpus = atomic_read(&kvm->online_vcpus); |
@@ -1859,16 +1852,28 @@ static int vgic_init_maps(struct kvm *kvm) | |||
1859 | if (ret) | 1852 | if (ret) |
1860 | goto out; | 1853 | goto out; |
1861 | 1854 | ||
1862 | kvm_for_each_vcpu(i, vcpu, kvm) { | 1855 | for (i = VGIC_NR_PRIVATE_IRQS; i < dist->nr_irqs; i += 4) |
1856 | vgic_set_target_reg(kvm, 0, i); | ||
1857 | |||
1858 | kvm_for_each_vcpu(vcpu_id, vcpu, kvm) { | ||
1863 | ret = vgic_vcpu_init_maps(vcpu, nr_irqs); | 1859 | ret = vgic_vcpu_init_maps(vcpu, nr_irqs); |
1864 | if (ret) { | 1860 | if (ret) { |
1865 | kvm_err("VGIC: Failed to allocate vcpu memory\n"); | 1861 | kvm_err("VGIC: Failed to allocate vcpu memory\n"); |
1866 | break; | 1862 | break; |
1867 | } | 1863 | } |
1868 | } | ||
1869 | 1864 | ||
1870 | for (i = VGIC_NR_PRIVATE_IRQS; i < dist->nr_irqs; i += 4) | 1865 | for (i = 0; i < dist->nr_irqs; i++) { |
1871 | vgic_set_target_reg(kvm, 0, i); | 1866 | if (i < VGIC_NR_PPIS) |
1867 | vgic_bitmap_set_irq_val(&dist->irq_enabled, | ||
1868 | vcpu->vcpu_id, i, 1); | ||
1869 | if (i < VGIC_NR_PRIVATE_IRQS) | ||
1870 | vgic_bitmap_set_irq_val(&dist->irq_cfg, | ||
1871 | vcpu->vcpu_id, i, | ||
1872 | VGIC_CFG_EDGE); | ||
1873 | } | ||
1874 | |||
1875 | vgic_enable(vcpu); | ||
1876 | } | ||
1872 | 1877 | ||
1873 | out: | 1878 | out: |
1874 | if (ret) | 1879 | if (ret) |
@@ -1878,25 +1883,23 @@ out: | |||
1878 | } | 1883 | } |
1879 | 1884 | ||
1880 | /** | 1885 | /** |
1881 | * kvm_vgic_init - Initialize global VGIC state before running any VCPUs | 1886 | * kvm_vgic_map_resources - Configure global VGIC state before running any VCPUs |
1882 | * @kvm: pointer to the kvm struct | 1887 | * @kvm: pointer to the kvm struct |
1883 | * | 1888 | * |
1884 | * Map the virtual CPU interface into the VM before running any VCPUs. We | 1889 | * Map the virtual CPU interface into the VM before running any VCPUs. We |
1885 | * can't do this at creation time, because user space must first set the | 1890 | * can't do this at creation time, because user space must first set the |
1886 | * virtual CPU interface address in the guest physical address space. Also | 1891 | * virtual CPU interface address in the guest physical address space. |
1887 | * initialize the ITARGETSRn regs to 0 on the emulated distributor. | ||
1888 | */ | 1892 | */ |
1889 | int kvm_vgic_init(struct kvm *kvm) | 1893 | int kvm_vgic_map_resources(struct kvm *kvm) |
1890 | { | 1894 | { |
1891 | struct kvm_vcpu *vcpu; | 1895 | int ret = 0; |
1892 | int ret = 0, i; | ||
1893 | 1896 | ||
1894 | if (!irqchip_in_kernel(kvm)) | 1897 | if (!irqchip_in_kernel(kvm)) |
1895 | return 0; | 1898 | return 0; |
1896 | 1899 | ||
1897 | mutex_lock(&kvm->lock); | 1900 | mutex_lock(&kvm->lock); |
1898 | 1901 | ||
1899 | if (vgic_initialized(kvm)) | 1902 | if (vgic_ready(kvm)) |
1900 | goto out; | 1903 | goto out; |
1901 | 1904 | ||
1902 | if (IS_VGIC_ADDR_UNDEF(kvm->arch.vgic.vgic_dist_base) || | 1905 | if (IS_VGIC_ADDR_UNDEF(kvm->arch.vgic.vgic_dist_base) || |
@@ -1906,7 +1909,11 @@ int kvm_vgic_init(struct kvm *kvm) | |||
1906 | goto out; | 1909 | goto out; |
1907 | } | 1910 | } |
1908 | 1911 | ||
1909 | ret = vgic_init_maps(kvm); | 1912 | /* |
1913 | * Initialize the vgic if this hasn't already been done on demand by | ||
1914 | * accessing the vgic state from userspace. | ||
1915 | */ | ||
1916 | ret = vgic_init(kvm); | ||
1910 | if (ret) { | 1917 | if (ret) { |
1911 | kvm_err("Unable to allocate maps\n"); | 1918 | kvm_err("Unable to allocate maps\n"); |
1912 | goto out; | 1919 | goto out; |
@@ -1920,9 +1927,6 @@ int kvm_vgic_init(struct kvm *kvm) | |||
1920 | goto out; | 1927 | goto out; |
1921 | } | 1928 | } |
1922 | 1929 | ||
1923 | kvm_for_each_vcpu(i, vcpu, kvm) | ||
1924 | kvm_vgic_vcpu_init(vcpu); | ||
1925 | |||
1926 | kvm->arch.vgic.ready = true; | 1930 | kvm->arch.vgic.ready = true; |
1927 | out: | 1931 | out: |
1928 | if (ret) | 1932 | if (ret) |
@@ -2167,7 +2171,7 @@ static int vgic_attr_regs_access(struct kvm_device *dev, | |||
2167 | 2171 | ||
2168 | mutex_lock(&dev->kvm->lock); | 2172 | mutex_lock(&dev->kvm->lock); |
2169 | 2173 | ||
2170 | ret = vgic_init_maps(dev->kvm); | 2174 | ret = vgic_init(dev->kvm); |
2171 | if (ret) | 2175 | if (ret) |
2172 | goto out; | 2176 | goto out; |
2173 | 2177 | ||
@@ -2289,7 +2293,7 @@ static int vgic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) | |||
2289 | 2293 | ||
2290 | mutex_lock(&dev->kvm->lock); | 2294 | mutex_lock(&dev->kvm->lock); |
2291 | 2295 | ||
2292 | if (vgic_initialized(dev->kvm) || dev->kvm->arch.vgic.nr_irqs) | 2296 | if (vgic_ready(dev->kvm) || dev->kvm->arch.vgic.nr_irqs) |
2293 | ret = -EBUSY; | 2297 | ret = -EBUSY; |
2294 | else | 2298 | else |
2295 | dev->kvm->arch.vgic.nr_irqs = val; | 2299 | dev->kvm->arch.vgic.nr_irqs = val; |
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index b0fb390943c6..148b2392c762 100644 --- a/virt/kvm/eventfd.c +++ b/virt/kvm/eventfd.c | |||
@@ -36,9 +36,6 @@ | |||
36 | #include <linux/seqlock.h> | 36 | #include <linux/seqlock.h> |
37 | #include <trace/events/kvm.h> | 37 | #include <trace/events/kvm.h> |
38 | 38 | ||
39 | #ifdef __KVM_HAVE_IOAPIC | ||
40 | #include "ioapic.h" | ||
41 | #endif | ||
42 | #include "iodev.h" | 39 | #include "iodev.h" |
43 | 40 | ||
44 | #ifdef CONFIG_HAVE_KVM_IRQFD | 41 | #ifdef CONFIG_HAVE_KVM_IRQFD |
@@ -492,9 +489,7 @@ void kvm_register_irq_ack_notifier(struct kvm *kvm, | |||
492 | mutex_lock(&kvm->irq_lock); | 489 | mutex_lock(&kvm->irq_lock); |
493 | hlist_add_head_rcu(&kian->link, &kvm->irq_ack_notifier_list); | 490 | hlist_add_head_rcu(&kian->link, &kvm->irq_ack_notifier_list); |
494 | mutex_unlock(&kvm->irq_lock); | 491 | mutex_unlock(&kvm->irq_lock); |
495 | #ifdef __KVM_HAVE_IOAPIC | ||
496 | kvm_vcpu_request_scan_ioapic(kvm); | 492 | kvm_vcpu_request_scan_ioapic(kvm); |
497 | #endif | ||
498 | } | 493 | } |
499 | 494 | ||
500 | void kvm_unregister_irq_ack_notifier(struct kvm *kvm, | 495 | void kvm_unregister_irq_ack_notifier(struct kvm *kvm, |
@@ -504,9 +499,7 @@ void kvm_unregister_irq_ack_notifier(struct kvm *kvm, | |||
504 | hlist_del_init_rcu(&kian->link); | 499 | hlist_del_init_rcu(&kian->link); |
505 | mutex_unlock(&kvm->irq_lock); | 500 | mutex_unlock(&kvm->irq_lock); |
506 | synchronize_srcu(&kvm->irq_srcu); | 501 | synchronize_srcu(&kvm->irq_srcu); |
507 | #ifdef __KVM_HAVE_IOAPIC | ||
508 | kvm_vcpu_request_scan_ioapic(kvm); | 502 | kvm_vcpu_request_scan_ioapic(kvm); |
509 | #endif | ||
510 | } | 503 | } |
511 | #endif | 504 | #endif |
512 | 505 | ||
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 3cee7b167052..f5283438ee05 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -124,15 +124,6 @@ int vcpu_load(struct kvm_vcpu *vcpu) | |||
124 | 124 | ||
125 | if (mutex_lock_killable(&vcpu->mutex)) | 125 | if (mutex_lock_killable(&vcpu->mutex)) |
126 | return -EINTR; | 126 | return -EINTR; |
127 | if (unlikely(vcpu->pid != current->pids[PIDTYPE_PID].pid)) { | ||
128 | /* The thread running this VCPU changed. */ | ||
129 | struct pid *oldpid = vcpu->pid; | ||
130 | struct pid *newpid = get_task_pid(current, PIDTYPE_PID); | ||
131 | rcu_assign_pointer(vcpu->pid, newpid); | ||
132 | if (oldpid) | ||
133 | synchronize_rcu(); | ||
134 | put_pid(oldpid); | ||
135 | } | ||
136 | cpu = get_cpu(); | 127 | cpu = get_cpu(); |
137 | preempt_notifier_register(&vcpu->preempt_notifier); | 128 | preempt_notifier_register(&vcpu->preempt_notifier); |
138 | kvm_arch_vcpu_load(vcpu, cpu); | 129 | kvm_arch_vcpu_load(vcpu, cpu); |
@@ -468,9 +459,6 @@ static struct kvm *kvm_create_vm(unsigned long type) | |||
468 | if (r) | 459 | if (r) |
469 | goto out_err_no_disable; | 460 | goto out_err_no_disable; |
470 | 461 | ||
471 | #ifdef CONFIG_HAVE_KVM_IRQCHIP | ||
472 | INIT_HLIST_HEAD(&kvm->mask_notifier_list); | ||
473 | #endif | ||
474 | #ifdef CONFIG_HAVE_KVM_IRQFD | 462 | #ifdef CONFIG_HAVE_KVM_IRQFD |
475 | INIT_HLIST_HEAD(&kvm->irq_ack_notifier_list); | 463 | INIT_HLIST_HEAD(&kvm->irq_ack_notifier_list); |
476 | #endif | 464 | #endif |
@@ -668,48 +656,46 @@ static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot) | |||
668 | return 0; | 656 | return 0; |
669 | } | 657 | } |
670 | 658 | ||
671 | static int cmp_memslot(const void *slot1, const void *slot2) | ||
672 | { | ||
673 | struct kvm_memory_slot *s1, *s2; | ||
674 | |||
675 | s1 = (struct kvm_memory_slot *)slot1; | ||
676 | s2 = (struct kvm_memory_slot *)slot2; | ||
677 | |||
678 | if (s1->npages < s2->npages) | ||
679 | return 1; | ||
680 | if (s1->npages > s2->npages) | ||
681 | return -1; | ||
682 | |||
683 | return 0; | ||
684 | } | ||
685 | |||
686 | /* | 659 | /* |
687 | * Sort the memslots base on its size, so the larger slots | 660 | * Insert memslot and re-sort memslots based on their GFN, |
688 | * will get better fit. | 661 | * so binary search could be used to lookup GFN. |
662 | * Sorting algorithm takes advantage of having initially | ||
663 | * sorted array and known changed memslot position. | ||
689 | */ | 664 | */ |
690 | static void sort_memslots(struct kvm_memslots *slots) | ||
691 | { | ||
692 | int i; | ||
693 | |||
694 | sort(slots->memslots, KVM_MEM_SLOTS_NUM, | ||
695 | sizeof(struct kvm_memory_slot), cmp_memslot, NULL); | ||
696 | |||
697 | for (i = 0; i < KVM_MEM_SLOTS_NUM; i++) | ||
698 | slots->id_to_index[slots->memslots[i].id] = i; | ||
699 | } | ||
700 | |||
701 | static void update_memslots(struct kvm_memslots *slots, | 665 | static void update_memslots(struct kvm_memslots *slots, |
702 | struct kvm_memory_slot *new) | 666 | struct kvm_memory_slot *new) |
703 | { | 667 | { |
704 | if (new) { | 668 | int id = new->id; |
705 | int id = new->id; | 669 | int i = slots->id_to_index[id]; |
706 | struct kvm_memory_slot *old = id_to_memslot(slots, id); | 670 | struct kvm_memory_slot *mslots = slots->memslots; |
707 | unsigned long npages = old->npages; | ||
708 | 671 | ||
709 | *old = *new; | 672 | WARN_ON(mslots[i].id != id); |
710 | if (new->npages != npages) | 673 | if (!new->npages) { |
711 | sort_memslots(slots); | 674 | new->base_gfn = 0; |
675 | if (mslots[i].npages) | ||
676 | slots->used_slots--; | ||
677 | } else { | ||
678 | if (!mslots[i].npages) | ||
679 | slots->used_slots++; | ||
712 | } | 680 | } |
681 | |||
682 | while (i < KVM_MEM_SLOTS_NUM - 1 && | ||
683 | new->base_gfn <= mslots[i + 1].base_gfn) { | ||
684 | if (!mslots[i + 1].npages) | ||
685 | break; | ||
686 | mslots[i] = mslots[i + 1]; | ||
687 | slots->id_to_index[mslots[i].id] = i; | ||
688 | i++; | ||
689 | } | ||
690 | while (i > 0 && | ||
691 | new->base_gfn > mslots[i - 1].base_gfn) { | ||
692 | mslots[i] = mslots[i - 1]; | ||
693 | slots->id_to_index[mslots[i].id] = i; | ||
694 | i--; | ||
695 | } | ||
696 | |||
697 | mslots[i] = *new; | ||
698 | slots->id_to_index[mslots[i].id] = i; | ||
713 | } | 699 | } |
714 | 700 | ||
715 | static int check_memory_region_flags(struct kvm_userspace_memory_region *mem) | 701 | static int check_memory_region_flags(struct kvm_userspace_memory_region *mem) |
@@ -727,7 +713,7 @@ static int check_memory_region_flags(struct kvm_userspace_memory_region *mem) | |||
727 | } | 713 | } |
728 | 714 | ||
729 | static struct kvm_memslots *install_new_memslots(struct kvm *kvm, | 715 | static struct kvm_memslots *install_new_memslots(struct kvm *kvm, |
730 | struct kvm_memslots *slots, struct kvm_memory_slot *new) | 716 | struct kvm_memslots *slots) |
731 | { | 717 | { |
732 | struct kvm_memslots *old_memslots = kvm->memslots; | 718 | struct kvm_memslots *old_memslots = kvm->memslots; |
733 | 719 | ||
@@ -738,7 +724,6 @@ static struct kvm_memslots *install_new_memslots(struct kvm *kvm, | |||
738 | WARN_ON(old_memslots->generation & 1); | 724 | WARN_ON(old_memslots->generation & 1); |
739 | slots->generation = old_memslots->generation + 1; | 725 | slots->generation = old_memslots->generation + 1; |
740 | 726 | ||
741 | update_memslots(slots, new); | ||
742 | rcu_assign_pointer(kvm->memslots, slots); | 727 | rcu_assign_pointer(kvm->memslots, slots); |
743 | synchronize_srcu_expedited(&kvm->srcu); | 728 | synchronize_srcu_expedited(&kvm->srcu); |
744 | 729 | ||
@@ -760,7 +745,7 @@ static struct kvm_memslots *install_new_memslots(struct kvm *kvm, | |||
760 | * | 745 | * |
761 | * Discontiguous memory is allowed, mostly for framebuffers. | 746 | * Discontiguous memory is allowed, mostly for framebuffers. |
762 | * | 747 | * |
763 | * Must be called holding mmap_sem for write. | 748 | * Must be called holding kvm->slots_lock for write. |
764 | */ | 749 | */ |
765 | int __kvm_set_memory_region(struct kvm *kvm, | 750 | int __kvm_set_memory_region(struct kvm *kvm, |
766 | struct kvm_userspace_memory_region *mem) | 751 | struct kvm_userspace_memory_region *mem) |
@@ -866,15 +851,16 @@ int __kvm_set_memory_region(struct kvm *kvm, | |||
866 | goto out_free; | 851 | goto out_free; |
867 | } | 852 | } |
868 | 853 | ||
854 | slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots), | ||
855 | GFP_KERNEL); | ||
856 | if (!slots) | ||
857 | goto out_free; | ||
858 | |||
869 | if ((change == KVM_MR_DELETE) || (change == KVM_MR_MOVE)) { | 859 | if ((change == KVM_MR_DELETE) || (change == KVM_MR_MOVE)) { |
870 | slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots), | ||
871 | GFP_KERNEL); | ||
872 | if (!slots) | ||
873 | goto out_free; | ||
874 | slot = id_to_memslot(slots, mem->slot); | 860 | slot = id_to_memslot(slots, mem->slot); |
875 | slot->flags |= KVM_MEMSLOT_INVALID; | 861 | slot->flags |= KVM_MEMSLOT_INVALID; |
876 | 862 | ||
877 | old_memslots = install_new_memslots(kvm, slots, NULL); | 863 | old_memslots = install_new_memslots(kvm, slots); |
878 | 864 | ||
879 | /* slot was deleted or moved, clear iommu mapping */ | 865 | /* slot was deleted or moved, clear iommu mapping */ |
880 | kvm_iommu_unmap_pages(kvm, &old); | 866 | kvm_iommu_unmap_pages(kvm, &old); |
@@ -886,6 +872,12 @@ int __kvm_set_memory_region(struct kvm *kvm, | |||
886 | * - kvm_is_visible_gfn (mmu_check_roots) | 872 | * - kvm_is_visible_gfn (mmu_check_roots) |
887 | */ | 873 | */ |
888 | kvm_arch_flush_shadow_memslot(kvm, slot); | 874 | kvm_arch_flush_shadow_memslot(kvm, slot); |
875 | |||
876 | /* | ||
877 | * We can re-use the old_memslots from above, the only difference | ||
878 | * from the currently installed memslots is the invalid flag. This | ||
879 | * will get overwritten by update_memslots anyway. | ||
880 | */ | ||
889 | slots = old_memslots; | 881 | slots = old_memslots; |
890 | } | 882 | } |
891 | 883 | ||
@@ -893,26 +885,14 @@ int __kvm_set_memory_region(struct kvm *kvm, | |||
893 | if (r) | 885 | if (r) |
894 | goto out_slots; | 886 | goto out_slots; |
895 | 887 | ||
896 | r = -ENOMEM; | ||
897 | /* | ||
898 | * We can re-use the old_memslots from above, the only difference | ||
899 | * from the currently installed memslots is the invalid flag. This | ||
900 | * will get overwritten by update_memslots anyway. | ||
901 | */ | ||
902 | if (!slots) { | ||
903 | slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots), | ||
904 | GFP_KERNEL); | ||
905 | if (!slots) | ||
906 | goto out_free; | ||
907 | } | ||
908 | |||
909 | /* actual memory is freed via old in kvm_free_physmem_slot below */ | 888 | /* actual memory is freed via old in kvm_free_physmem_slot below */ |
910 | if (change == KVM_MR_DELETE) { | 889 | if (change == KVM_MR_DELETE) { |
911 | new.dirty_bitmap = NULL; | 890 | new.dirty_bitmap = NULL; |
912 | memset(&new.arch, 0, sizeof(new.arch)); | 891 | memset(&new.arch, 0, sizeof(new.arch)); |
913 | } | 892 | } |
914 | 893 | ||
915 | old_memslots = install_new_memslots(kvm, slots, &new); | 894 | update_memslots(slots, &new); |
895 | old_memslots = install_new_memslots(kvm, slots); | ||
916 | 896 | ||
917 | kvm_arch_commit_memory_region(kvm, mem, &old, change); | 897 | kvm_arch_commit_memory_region(kvm, mem, &old, change); |
918 | 898 | ||
@@ -1799,10 +1779,6 @@ int kvm_vcpu_yield_to(struct kvm_vcpu *target) | |||
1799 | rcu_read_unlock(); | 1779 | rcu_read_unlock(); |
1800 | if (!task) | 1780 | if (!task) |
1801 | return ret; | 1781 | return ret; |
1802 | if (task->flags & PF_VCPU) { | ||
1803 | put_task_struct(task); | ||
1804 | return ret; | ||
1805 | } | ||
1806 | ret = yield_to(task, 1); | 1782 | ret = yield_to(task, 1); |
1807 | put_task_struct(task); | 1783 | put_task_struct(task); |
1808 | 1784 | ||
@@ -2065,6 +2041,15 @@ static long kvm_vcpu_ioctl(struct file *filp, | |||
2065 | r = -EINVAL; | 2041 | r = -EINVAL; |
2066 | if (arg) | 2042 | if (arg) |
2067 | goto out; | 2043 | goto out; |
2044 | if (unlikely(vcpu->pid != current->pids[PIDTYPE_PID].pid)) { | ||
2045 | /* The thread running this VCPU changed. */ | ||
2046 | struct pid *oldpid = vcpu->pid; | ||
2047 | struct pid *newpid = get_task_pid(current, PIDTYPE_PID); | ||
2048 | rcu_assign_pointer(vcpu->pid, newpid); | ||
2049 | if (oldpid) | ||
2050 | synchronize_rcu(); | ||
2051 | put_pid(oldpid); | ||
2052 | } | ||
2068 | r = kvm_arch_vcpu_ioctl_run(vcpu, vcpu->run); | 2053 | r = kvm_arch_vcpu_ioctl_run(vcpu, vcpu->run); |
2069 | trace_kvm_userspace_exit(vcpu->run->exit_reason, r); | 2054 | trace_kvm_userspace_exit(vcpu->run->exit_reason, r); |
2070 | break; | 2055 | break; |
@@ -2599,8 +2584,6 @@ static long kvm_vm_ioctl(struct file *filp, | |||
2599 | break; | 2584 | break; |
2600 | default: | 2585 | default: |
2601 | r = kvm_arch_vm_ioctl(filp, ioctl, arg); | 2586 | r = kvm_arch_vm_ioctl(filp, ioctl, arg); |
2602 | if (r == -ENOTTY) | ||
2603 | r = kvm_vm_ioctl_assigned_device(kvm, ioctl, arg); | ||
2604 | } | 2587 | } |
2605 | out: | 2588 | out: |
2606 | return r; | 2589 | return r; |