diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-07 14:35:30 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-07 14:35:30 -0400 |
| commit | 66bb0aa077978dbb76e6283531eb3cc7a878de38 (patch) | |
| tree | 62a28a96cb43df2d8f7c6eb14d4676a1e2ce3887 | |
| parent | e306e3be1cbe5b11d0f8a53a557c205cf27e4979 (diff) | |
| parent | c77dcacb397519b6ade8f08201a4a90a7f4f751e (diff) | |
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull second round of KVM changes from Paolo Bonzini:
"Here are the PPC and ARM changes for KVM, which I separated because
they had small conflicts (respectively within KVM documentation, and
with 3.16-rc changes). Since they were all within the subsystem, I
took care of them.
Stephen Rothwell reported some snags in PPC builds, but they are all
fixed now; the latest linux-next report was clean.
New features for ARM include:
- KVM VGIC v2 emulation on GICv3 hardware
- Big-Endian support for arm/arm64 (guest and host)
- Debug Architecture support for arm64 (arm32 is on Christoffer's todo list)
And for PPC:
- Book3S: Good number of LE host fixes, enable HV on LE
- Book3S HV: Add in-guest debug support
This release drops support for KVM on the PPC440. As a result, the
PPC merge removes more lines than it adds. :)
I also included an x86 change, since Davidlohr tied it to an
independent bug report and the reporter quickly provided a Tested-by;
there was no reason to wait for -rc2"
* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (122 commits)
KVM: Move more code under CONFIG_HAVE_KVM_IRQFD
KVM: nVMX: fix "acknowledge interrupt on exit" when APICv is in use
KVM: nVMX: Fix nested vmexit ack intr before load vmcs01
KVM: PPC: Enable IRQFD support for the XICS interrupt controller
KVM: Give IRQFD its own separate enabling Kconfig option
KVM: Move irq notifier implementation into eventfd.c
KVM: Move all accesses to kvm::irq_routing into irqchip.c
KVM: irqchip: Provide and use accessors for irq routing table
KVM: Don't keep reference to irq routing table in irqfd struct
KVM: PPC: drop duplicate tracepoint
arm64: KVM: fix 64bit CP15 VM access for 32bit guests
KVM: arm64: GICv3: mandate page-aligned GICV region
arm64: KVM: GICv3: move system register access to msr_s/mrs_s
KVM: PPC: PR: Handle FSCR feature deselects
KVM: PPC: HV: Remove generic instruction emulation
KVM: PPC: BOOKEHV: rename e500hv_spr to bookehv_spr
KVM: PPC: Remove DCR handling
KVM: PPC: Expose helper functions for data/inst faults
KVM: PPC: Separate loadstore emulation from priv emulation
KVM: PPC: Handle magic page in kvmppc_ld/st
...
116 files changed, 5010 insertions, 2825 deletions
diff --git a/Documentation/arm64/booting.txt b/Documentation/arm64/booting.txt index 85af34d55cee..f3c05b5f9f08 100644 --- a/Documentation/arm64/booting.txt +++ b/Documentation/arm64/booting.txt | |||
| @@ -168,6 +168,14 @@ Before jumping into the kernel, the following conditions must be met: | |||
| 168 | the kernel image will be entered must be initialised by software at a | 168 | the kernel image will be entered must be initialised by software at a |
| 169 | higher exception level to prevent execution in an UNKNOWN state. | 169 | higher exception level to prevent execution in an UNKNOWN state. |
| 170 | 170 | ||
| 171 | For systems with a GICv3 interrupt controller: | ||
| 172 | - If EL3 is present: | ||
| 173 | ICC_SRE_EL3.Enable (bit 3) must be initialiased to 0b1. | ||
| 174 | ICC_SRE_EL3.SRE (bit 0) must be initialised to 0b1. | ||
| 175 | - If the kernel is entered at EL1: | ||
| 176 | ICC.SRE_EL2.Enable (bit 3) must be initialised to 0b1 | ||
| 177 | ICC_SRE_EL2.SRE (bit 0) must be initialised to 0b1. | ||
| 178 | |||
| 171 | The requirements described above for CPU mode, caches, MMUs, architected | 179 | The requirements described above for CPU mode, caches, MMUs, architected |
| 172 | timers, coherency and system registers apply to all CPUs. All CPUs must | 180 | timers, coherency and system registers apply to all CPUs. All CPUs must |
| 173 | enter the kernel in the same exception level. | 181 | enter the kernel in the same exception level. |
diff --git a/Documentation/devicetree/bindings/arm/gic-v3.txt b/Documentation/devicetree/bindings/arm/gic-v3.txt new file mode 100644 index 000000000000..33cd05e6c125 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/gic-v3.txt | |||
| @@ -0,0 +1,79 @@ | |||
| 1 | * ARM Generic Interrupt Controller, version 3 | ||
| 2 | |||
| 3 | AArch64 SMP cores are often associated with a GICv3, providing Private | ||
| 4 | Peripheral Interrupts (PPI), Shared Peripheral Interrupts (SPI), | ||
| 5 | Software Generated Interrupts (SGI), and Locality-specific Peripheral | ||
| 6 | Interrupts (LPI). | ||
| 7 | |||
| 8 | Main node required properties: | ||
| 9 | |||
| 10 | - compatible : should at least contain "arm,gic-v3". | ||
| 11 | - interrupt-controller : Identifies the node as an interrupt controller | ||
| 12 | - #interrupt-cells : Specifies the number of cells needed to encode an | ||
| 13 | interrupt source. Must be a single cell with a value of at least 3. | ||
| 14 | |||
| 15 | The 1st cell is the interrupt type; 0 for SPI interrupts, 1 for PPI | ||
| 16 | interrupts. Other values are reserved for future use. | ||
| 17 | |||
| 18 | The 2nd cell contains the interrupt number for the interrupt type. | ||
| 19 | SPI interrupts are in the range [0-987]. PPI interrupts are in the | ||
| 20 | range [0-15]. | ||
| 21 | |||
| 22 | The 3rd cell is the flags, encoded as follows: | ||
| 23 | bits[3:0] trigger type and level flags. | ||
| 24 | 1 = edge triggered | ||
| 25 | 4 = level triggered | ||
| 26 | |||
| 27 | Cells 4 and beyond are reserved for future use. When the 1st cell | ||
| 28 | has a value of 0 or 1, cells 4 and beyond act as padding, and may be | ||
| 29 | ignored. It is recommended that padding cells have a value of 0. | ||
| 30 | |||
| 31 | - reg : Specifies base physical address(s) and size of the GIC | ||
| 32 | registers, in the following order: | ||
| 33 | - GIC Distributor interface (GICD) | ||
| 34 | - GIC Redistributors (GICR), one range per redistributor region | ||
| 35 | - GIC CPU interface (GICC) | ||
| 36 | - GIC Hypervisor interface (GICH) | ||
| 37 | - GIC Virtual CPU interface (GICV) | ||
| 38 | |||
| 39 | GICC, GICH and GICV are optional. | ||
| 40 | |||
| 41 | - interrupts : Interrupt source of the VGIC maintenance interrupt. | ||
| 42 | |||
| 43 | Optional | ||
| 44 | |||
| 45 | - redistributor-stride : If using padding pages, specifies the stride | ||
| 46 | of consecutive redistributors. Must be a multiple of 64kB. | ||
| 47 | |||
| 48 | - #redistributor-regions: The number of independent contiguous regions | ||
| 49 | occupied by the redistributors. Required if more than one such | ||
| 50 | region is present. | ||
| 51 | |||
| 52 | Examples: | ||
| 53 | |||
| 54 | gic: interrupt-controller@2cf00000 { | ||
| 55 | compatible = "arm,gic-v3"; | ||
| 56 | #interrupt-cells = <3>; | ||
| 57 | interrupt-controller; | ||
| 58 | reg = <0x0 0x2f000000 0 0x10000>, // GICD | ||
| 59 | <0x0 0x2f100000 0 0x200000>, // GICR | ||
| 60 | <0x0 0x2c000000 0 0x2000>, // GICC | ||
| 61 | <0x0 0x2c010000 0 0x2000>, // GICH | ||
| 62 | <0x0 0x2c020000 0 0x2000>; // GICV | ||
| 63 | interrupts = <1 9 4>; | ||
| 64 | }; | ||
| 65 | |||
| 66 | gic: interrupt-controller@2c010000 { | ||
| 67 | compatible = "arm,gic-v3"; | ||
| 68 | #interrupt-cells = <3>; | ||
| 69 | interrupt-controller; | ||
| 70 | redistributor-stride = <0x0 0x40000>; // 256kB stride | ||
| 71 | #redistributor-regions = <2>; | ||
| 72 | reg = <0x0 0x2c010000 0 0x10000>, // GICD | ||
| 73 | <0x0 0x2d000000 0 0x800000>, // GICR 1: CPUs 0-31 | ||
| 74 | <0x0 0x2e000000 0 0x800000>; // GICR 2: CPUs 32-63 | ||
| 75 | <0x0 0x2c040000 0 0x2000>, // GICC | ||
| 76 | <0x0 0x2c060000 0 0x2000>, // GICH | ||
| 77 | <0x0 0x2c080000 0 0x2000>; // GICV | ||
| 78 | interrupts = <1 9 4>; | ||
| 79 | }; | ||
diff --git a/Documentation/powerpc/00-INDEX b/Documentation/powerpc/00-INDEX index 6db73df04278..a68784d0a1ee 100644 --- a/Documentation/powerpc/00-INDEX +++ b/Documentation/powerpc/00-INDEX | |||
| @@ -17,8 +17,6 @@ firmware-assisted-dump.txt | |||
| 17 | - Documentation on the firmware assisted dump mechanism "fadump". | 17 | - Documentation on the firmware assisted dump mechanism "fadump". |
| 18 | hvcs.txt | 18 | hvcs.txt |
| 19 | - IBM "Hypervisor Virtual Console Server" Installation Guide | 19 | - IBM "Hypervisor Virtual Console Server" Installation Guide |
| 20 | kvm_440.txt | ||
| 21 | - Various notes on the implementation of KVM for PowerPC 440. | ||
| 22 | mpc52xx.txt | 20 | mpc52xx.txt |
| 23 | - Linux 2.6.x on MPC52xx family | 21 | - Linux 2.6.x on MPC52xx family |
| 24 | pmu-ebb.txt | 22 | pmu-ebb.txt |
diff --git a/Documentation/powerpc/kvm_440.txt b/Documentation/powerpc/kvm_440.txt deleted file mode 100644 index c02a003fa03a..000000000000 --- a/Documentation/powerpc/kvm_440.txt +++ /dev/null | |||
| @@ -1,41 +0,0 @@ | |||
| 1 | Hollis Blanchard <hollisb@us.ibm.com> | ||
| 2 | 15 Apr 2008 | ||
| 3 | |||
| 4 | Various notes on the implementation of KVM for PowerPC 440: | ||
| 5 | |||
| 6 | To enforce isolation, host userspace, guest kernel, and guest userspace all | ||
| 7 | run at user privilege level. Only the host kernel runs in supervisor mode. | ||
| 8 | Executing privileged instructions in the guest traps into KVM (in the host | ||
| 9 | kernel), where we decode and emulate them. Through this technique, unmodified | ||
| 10 | 440 Linux kernels can be run (slowly) as guests. Future performance work will | ||
| 11 | focus on reducing the overhead and frequency of these traps. | ||
| 12 | |||
| 13 | The usual code flow is started from userspace invoking an "run" ioctl, which | ||
| 14 | causes KVM to switch into guest context. We use IVPR to hijack the host | ||
| 15 | interrupt vectors while running the guest, which allows us to direct all | ||
| 16 | interrupts to kvmppc_handle_interrupt(). At this point, we could either | ||
| 17 | - handle the interrupt completely (e.g. emulate "mtspr SPRG0"), or | ||
| 18 | - let the host interrupt handler run (e.g. when the decrementer fires), or | ||
| 19 | - return to host userspace (e.g. when the guest performs device MMIO) | ||
| 20 | |||
| 21 | Address spaces: We take advantage of the fact that Linux doesn't use the AS=1 | ||
| 22 | address space (in host or guest), which gives us virtual address space to use | ||
| 23 | for guest mappings. While the guest is running, the host kernel remains mapped | ||
| 24 | in AS=0, but the guest can only use AS=1 mappings. | ||
| 25 | |||
| 26 | TLB entries: The TLB entries covering the host linear mapping remain | ||
| 27 | present while running the guest. This reduces the overhead of lightweight | ||
| 28 | exits, which are handled by KVM running in the host kernel. We keep three | ||
| 29 | copies of the TLB: | ||
| 30 | - guest TLB: contents of the TLB as the guest sees it | ||
| 31 | - shadow TLB: the TLB that is actually in hardware while guest is running | ||
| 32 | - host TLB: to restore TLB state when context switching guest -> host | ||
| 33 | When a TLB miss occurs because a mapping was not present in the shadow TLB, | ||
| 34 | but was present in the guest TLB, KVM handles the fault without invoking the | ||
| 35 | guest. Large guest pages are backed by multiple 4KB shadow pages through this | ||
| 36 | mechanism. | ||
| 37 | |||
| 38 | IO: MMIO and DCR accesses are emulated by userspace. We use virtio for network | ||
| 39 | and block IO, so those drivers must be enabled in the guest. It's possible | ||
| 40 | that some qemu device emulation (e.g. e1000 or rtl8139) may also work with | ||
| 41 | little effort. | ||
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 68cda1fc3d52..beae3fde075e 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt | |||
| @@ -148,9 +148,9 @@ of banks, as set via the KVM_X86_SETUP_MCE ioctl. | |||
| 148 | 148 | ||
| 149 | 4.4 KVM_CHECK_EXTENSION | 149 | 4.4 KVM_CHECK_EXTENSION |
| 150 | 150 | ||
| 151 | Capability: basic | 151 | Capability: basic, KVM_CAP_CHECK_EXTENSION_VM for vm ioctl |
| 152 | Architectures: all | 152 | Architectures: all |
| 153 | Type: system ioctl | 153 | Type: system ioctl, vm ioctl |
| 154 | Parameters: extension identifier (KVM_CAP_*) | 154 | Parameters: extension identifier (KVM_CAP_*) |
| 155 | Returns: 0 if unsupported; 1 (or some other positive integer) if supported | 155 | Returns: 0 if unsupported; 1 (or some other positive integer) if supported |
| 156 | 156 | ||
| @@ -160,6 +160,9 @@ receives an integer that describes the extension availability. | |||
| 160 | Generally 0 means no and 1 means yes, but some extensions may report | 160 | Generally 0 means no and 1 means yes, but some extensions may report |
| 161 | additional information in the integer return value. | 161 | additional information in the integer return value. |
| 162 | 162 | ||
| 163 | Based on their initialization different VMs may have different capabilities. | ||
| 164 | It is thus encouraged to use the vm ioctl to query for capabilities (available | ||
| 165 | with KVM_CAP_CHECK_EXTENSION_VM on the vm fd) | ||
| 163 | 166 | ||
| 164 | 4.5 KVM_GET_VCPU_MMAP_SIZE | 167 | 4.5 KVM_GET_VCPU_MMAP_SIZE |
| 165 | 168 | ||
| @@ -1892,7 +1895,8 @@ registers, find a list below: | |||
| 1892 | PPC | KVM_REG_PPC_PID | 64 | 1895 | PPC | KVM_REG_PPC_PID | 64 |
| 1893 | PPC | KVM_REG_PPC_ACOP | 64 | 1896 | PPC | KVM_REG_PPC_ACOP | 64 |
| 1894 | PPC | KVM_REG_PPC_VRSAVE | 32 | 1897 | PPC | KVM_REG_PPC_VRSAVE | 32 |
| 1895 | PPC | KVM_REG_PPC_LPCR | 64 | 1898 | PPC | KVM_REG_PPC_LPCR | 32 |
| 1899 | PPC | KVM_REG_PPC_LPCR_64 | 64 | ||
| 1896 | PPC | KVM_REG_PPC_PPR | 64 | 1900 | PPC | KVM_REG_PPC_PPR | 64 |
| 1897 | PPC | KVM_REG_PPC_ARCH_COMPAT | 32 | 1901 | PPC | KVM_REG_PPC_ARCH_COMPAT | 32 |
| 1898 | PPC | KVM_REG_PPC_DABRX | 32 | 1902 | PPC | KVM_REG_PPC_DABRX | 32 |
| @@ -2677,8 +2681,8 @@ The 'data' member contains, in its first 'len' bytes, the value as it would | |||
| 2677 | appear if the VCPU performed a load or store of the appropriate width directly | 2681 | appear if the VCPU performed a load or store of the appropriate width directly |
| 2678 | to the byte array. | 2682 | to the byte array. |
| 2679 | 2683 | ||
| 2680 | NOTE: For KVM_EXIT_IO, KVM_EXIT_MMIO, KVM_EXIT_OSI, KVM_EXIT_DCR, | 2684 | NOTE: For KVM_EXIT_IO, KVM_EXIT_MMIO, KVM_EXIT_OSI, KVM_EXIT_PAPR and |
| 2681 | KVM_EXIT_PAPR and KVM_EXIT_EPR the corresponding | 2685 | KVM_EXIT_EPR the corresponding |
| 2682 | operations are complete (and guest state is consistent) only after userspace | 2686 | operations are complete (and guest state is consistent) only after userspace |
| 2683 | has re-entered the kernel with KVM_RUN. The kernel side will first finish | 2687 | has re-entered the kernel with KVM_RUN. The kernel side will first finish |
| 2684 | incomplete operations and then check for pending signals. Userspace | 2688 | incomplete operations and then check for pending signals. Userspace |
| @@ -2749,7 +2753,7 @@ Principles of Operation Book in the Chapter for Dynamic Address Translation | |||
| 2749 | __u8 is_write; | 2753 | __u8 is_write; |
| 2750 | } dcr; | 2754 | } dcr; |
| 2751 | 2755 | ||
| 2752 | powerpc specific. | 2756 | Deprecated - was used for 440 KVM. |
| 2753 | 2757 | ||
| 2754 | /* KVM_EXIT_OSI */ | 2758 | /* KVM_EXIT_OSI */ |
| 2755 | struct { | 2759 | struct { |
| @@ -2931,8 +2935,8 @@ The fields in each entry are defined as follows: | |||
| 2931 | this function/index combination | 2935 | this function/index combination |
| 2932 | 2936 | ||
| 2933 | 2937 | ||
| 2934 | 6. Capabilities that can be enabled | 2938 | 6. Capabilities that can be enabled on vCPUs |
| 2935 | ----------------------------------- | 2939 | -------------------------------------------- |
| 2936 | 2940 | ||
| 2937 | There are certain capabilities that change the behavior of the virtual CPU or | 2941 | There are certain capabilities that change the behavior of the virtual CPU or |
| 2938 | the virtual machine when enabled. To enable them, please see section 4.37. | 2942 | the virtual machine when enabled. To enable them, please see section 4.37. |
| @@ -3091,3 +3095,43 @@ Parameters: none | |||
| 3091 | 3095 | ||
| 3092 | This capability enables the in-kernel irqchip for s390. Please refer to | 3096 | This capability enables the in-kernel irqchip for s390. Please refer to |
| 3093 | "4.24 KVM_CREATE_IRQCHIP" for details. | 3097 | "4.24 KVM_CREATE_IRQCHIP" for details. |
| 3098 | |||
| 3099 | 7. Capabilities that can be enabled on VMs | ||
| 3100 | ------------------------------------------ | ||
| 3101 | |||
| 3102 | There are certain capabilities that change the behavior of the virtual | ||
| 3103 | machine when enabled. To enable them, please see section 4.37. Below | ||
| 3104 | you can find a list of capabilities and what their effect on the VM | ||
| 3105 | is when enabling them. | ||
| 3106 | |||
| 3107 | The following information is provided along with the description: | ||
| 3108 | |||
| 3109 | Architectures: which instruction set architectures provide this ioctl. | ||
| 3110 | x86 includes both i386 and x86_64. | ||
| 3111 | |||
| 3112 | Parameters: what parameters are accepted by the capability. | ||
| 3113 | |||
| 3114 | Returns: the return value. General error numbers (EBADF, ENOMEM, EINVAL) | ||
| 3115 | are not detailed, but errors with specific meanings are. | ||
| 3116 | |||
| 3117 | |||
| 3118 | 7.1 KVM_CAP_PPC_ENABLE_HCALL | ||
| 3119 | |||
| 3120 | Architectures: ppc | ||
| 3121 | Parameters: args[0] is the sPAPR hcall number | ||
| 3122 | args[1] is 0 to disable, 1 to enable in-kernel handling | ||
| 3123 | |||
| 3124 | This capability controls whether individual sPAPR hypercalls (hcalls) | ||
| 3125 | get handled by the kernel or not. Enabling or disabling in-kernel | ||
| 3126 | handling of an hcall is effective across the VM. On creation, an | ||
| 3127 | initial set of hcalls are enabled for in-kernel handling, which | ||
| 3128 | consists of those hcalls for which in-kernel handlers were implemented | ||
| 3129 | before this capability was implemented. If disabled, the kernel will | ||
| 3130 | not to attempt to handle the hcall, but will always exit to userspace | ||
| 3131 | to handle it. Note that it may not make sense to enable some and | ||
| 3132 | disable others of a group of related hcalls, but KVM does not prevent | ||
| 3133 | userspace from doing that. | ||
| 3134 | |||
| 3135 | If the hcall number specified is not one that has an in-kernel | ||
| 3136 | implementation, the KVM_ENABLE_CAP ioctl will fail with an EINVAL | ||
| 3137 | error. | ||
diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h index 53b3c4a50d5c..3a67bec72d0c 100644 --- a/arch/arm/include/asm/kvm_asm.h +++ b/arch/arm/include/asm/kvm_asm.h | |||
| @@ -61,6 +61,24 @@ | |||
| 61 | #define ARM_EXCEPTION_FIQ 6 | 61 | #define ARM_EXCEPTION_FIQ 6 |
| 62 | #define ARM_EXCEPTION_HVC 7 | 62 | #define ARM_EXCEPTION_HVC 7 |
| 63 | 63 | ||
| 64 | /* | ||
| 65 | * The rr_lo_hi macro swaps a pair of registers depending on | ||
| 66 | * current endianness. It is used in conjunction with ldrd and strd | ||
| 67 | * instructions that load/store a 64-bit value from/to memory to/from | ||
| 68 | * a pair of registers which are used with the mrrc and mcrr instructions. | ||
| 69 | * If used with the ldrd/strd instructions, the a1 parameter is the first | ||
| 70 | * source/destination register and the a2 parameter is the second | ||
| 71 | * source/destination register. Note that the ldrd/strd instructions | ||
| 72 | * already swap the bytes within the words correctly according to the | ||
| 73 | * endianness setting, but the order of the registers need to be effectively | ||
| 74 | * swapped when used with the mrrc/mcrr instructions. | ||
| 75 | */ | ||
| 76 | #ifdef CONFIG_CPU_ENDIAN_BE8 | ||
| 77 | #define rr_lo_hi(a1, a2) a2, a1 | ||
| 78 | #else | ||
| 79 | #define rr_lo_hi(a1, a2) a1, a2 | ||
| 80 | #endif | ||
| 81 | |||
| 64 | #ifndef __ASSEMBLY__ | 82 | #ifndef __ASSEMBLY__ |
| 65 | struct kvm; | 83 | struct kvm; |
| 66 | struct kvm_vcpu; | 84 | struct kvm_vcpu; |
diff --git a/arch/arm/include/asm/kvm_emulate.h b/arch/arm/include/asm/kvm_emulate.h index 0fa90c962ac8..69b746955fca 100644 --- a/arch/arm/include/asm/kvm_emulate.h +++ b/arch/arm/include/asm/kvm_emulate.h | |||
| @@ -185,9 +185,16 @@ static inline unsigned long vcpu_data_guest_to_host(struct kvm_vcpu *vcpu, | |||
| 185 | default: | 185 | default: |
| 186 | return be32_to_cpu(data); | 186 | return be32_to_cpu(data); |
| 187 | } | 187 | } |
| 188 | } else { | ||
| 189 | switch (len) { | ||
| 190 | case 1: | ||
| 191 | return data & 0xff; | ||
| 192 | case 2: | ||
| 193 | return le16_to_cpu(data & 0xffff); | ||
| 194 | default: | ||
| 195 | return le32_to_cpu(data); | ||
| 196 | } | ||
| 188 | } | 197 | } |
| 189 | |||
| 190 | return data; /* Leave LE untouched */ | ||
| 191 | } | 198 | } |
| 192 | 199 | ||
| 193 | static inline unsigned long vcpu_data_host_to_guest(struct kvm_vcpu *vcpu, | 200 | static inline unsigned long vcpu_data_host_to_guest(struct kvm_vcpu *vcpu, |
| @@ -203,9 +210,16 @@ static inline unsigned long vcpu_data_host_to_guest(struct kvm_vcpu *vcpu, | |||
| 203 | default: | 210 | default: |
| 204 | return cpu_to_be32(data); | 211 | return cpu_to_be32(data); |
| 205 | } | 212 | } |
| 213 | } else { | ||
| 214 | switch (len) { | ||
| 215 | case 1: | ||
| 216 | return data & 0xff; | ||
| 217 | case 2: | ||
| 218 | return cpu_to_le16(data & 0xffff); | ||
| 219 | default: | ||
| 220 | return cpu_to_le32(data); | ||
| 221 | } | ||
| 206 | } | 222 | } |
| 207 | |||
| 208 | return data; /* Leave LE untouched */ | ||
| 209 | } | 223 | } |
| 210 | 224 | ||
| 211 | #endif /* __ARM_KVM_EMULATE_H__ */ | 225 | #endif /* __ARM_KVM_EMULATE_H__ */ |
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 193ceaf01bfd..6dfb404f6c46 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h | |||
| @@ -225,10 +225,12 @@ static inline int kvm_arch_dev_ioctl_check_extension(long ext) | |||
| 225 | return 0; | 225 | return 0; |
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | static inline void vgic_arch_setup(const struct vgic_params *vgic) | ||
| 229 | { | ||
| 230 | BUG_ON(vgic->type != VGIC_V2); | ||
| 231 | } | ||
| 232 | |||
| 228 | int kvm_perf_init(void); | 233 | int kvm_perf_init(void); |
| 229 | int kvm_perf_teardown(void); | 234 | int kvm_perf_teardown(void); |
| 230 | 235 | ||
| 231 | u64 kvm_arm_timer_get_reg(struct kvm_vcpu *, u64 regid); | ||
| 232 | int kvm_arm_timer_set_reg(struct kvm_vcpu *, u64 regid, u64 value); | ||
| 233 | |||
| 234 | #endif /* __ARM_KVM_HOST_H__ */ | 236 | #endif /* __ARM_KVM_HOST_H__ */ |
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h index 5c7aa3c1519f..5cc0b0f5f72f 100644 --- a/arch/arm/include/asm/kvm_mmu.h +++ b/arch/arm/include/asm/kvm_mmu.h | |||
| @@ -127,6 +127,18 @@ static inline void kvm_set_s2pmd_writable(pmd_t *pmd) | |||
| 127 | (__boundary - 1 < (end) - 1)? __boundary: (end); \ | 127 | (__boundary - 1 < (end) - 1)? __boundary: (end); \ |
| 128 | }) | 128 | }) |
| 129 | 129 | ||
| 130 | static inline bool kvm_page_empty(void *ptr) | ||
| 131 | { | ||
| 132 | struct page *ptr_page = virt_to_page(ptr); | ||
| 133 | return page_count(ptr_page) == 1; | ||
| 134 | } | ||
| 135 | |||
| 136 | |||
| 137 | #define kvm_pte_table_empty(ptep) kvm_page_empty(ptep) | ||
| 138 | #define kvm_pmd_table_empty(pmdp) kvm_page_empty(pmdp) | ||
| 139 | #define kvm_pud_table_empty(pudp) (0) | ||
| 140 | |||
| 141 | |||
| 130 | struct kvm; | 142 | struct kvm; |
| 131 | 143 | ||
| 132 | #define kvm_flush_dcache_to_poc(a,l) __cpuc_flush_dcache_area((a), (l)) | 144 | #define kvm_flush_dcache_to_poc(a,l) __cpuc_flush_dcache_area((a), (l)) |
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index 85598b5d1efd..713e807621d2 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c | |||
| @@ -182,13 +182,13 @@ int main(void) | |||
| 182 | DEFINE(VCPU_HYP_PC, offsetof(struct kvm_vcpu, arch.fault.hyp_pc)); | 182 | DEFINE(VCPU_HYP_PC, offsetof(struct kvm_vcpu, arch.fault.hyp_pc)); |
| 183 | #ifdef CONFIG_KVM_ARM_VGIC | 183 | #ifdef CONFIG_KVM_ARM_VGIC |
| 184 | DEFINE(VCPU_VGIC_CPU, offsetof(struct kvm_vcpu, arch.vgic_cpu)); | 184 | DEFINE(VCPU_VGIC_CPU, offsetof(struct kvm_vcpu, arch.vgic_cpu)); |
| 185 | DEFINE(VGIC_CPU_HCR, offsetof(struct vgic_cpu, vgic_hcr)); | 185 | DEFINE(VGIC_V2_CPU_HCR, offsetof(struct vgic_cpu, vgic_v2.vgic_hcr)); |
| 186 | DEFINE(VGIC_CPU_VMCR, offsetof(struct vgic_cpu, vgic_vmcr)); | 186 | DEFINE(VGIC_V2_CPU_VMCR, offsetof(struct vgic_cpu, vgic_v2.vgic_vmcr)); |
| 187 | DEFINE(VGIC_CPU_MISR, offsetof(struct vgic_cpu, vgic_misr)); | 187 | DEFINE(VGIC_V2_CPU_MISR, offsetof(struct vgic_cpu, vgic_v2.vgic_misr)); |
| 188 | DEFINE(VGIC_CPU_EISR, offsetof(struct vgic_cpu, vgic_eisr)); | 188 | DEFINE(VGIC_V2_CPU_EISR, offsetof(struct vgic_cpu, vgic_v2.vgic_eisr)); |
| 189 | DEFINE(VGIC_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_elrsr)); | 189 | DEFINE(VGIC_V2_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_v2.vgic_elrsr)); |
| 190 | DEFINE(VGIC_CPU_APR, offsetof(struct vgic_cpu, vgic_apr)); | 190 | DEFINE(VGIC_V2_CPU_APR, offsetof(struct vgic_cpu, vgic_v2.vgic_apr)); |
| 191 | DEFINE(VGIC_CPU_LR, offsetof(struct vgic_cpu, vgic_lr)); | 191 | DEFINE(VGIC_V2_CPU_LR, offsetof(struct vgic_cpu, vgic_v2.vgic_lr)); |
| 192 | DEFINE(VGIC_CPU_NR_LR, offsetof(struct vgic_cpu, nr_lr)); | 192 | DEFINE(VGIC_CPU_NR_LR, offsetof(struct vgic_cpu, nr_lr)); |
| 193 | #ifdef CONFIG_KVM_ARM_TIMER | 193 | #ifdef CONFIG_KVM_ARM_TIMER |
| 194 | DEFINE(VCPU_TIMER_CNTV_CTL, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_ctl)); | 194 | DEFINE(VCPU_TIMER_CNTV_CTL, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_ctl)); |
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S index 56ce6290c831..2a55373f49bf 100644 --- a/arch/arm/kernel/hyp-stub.S +++ b/arch/arm/kernel/hyp-stub.S | |||
| @@ -134,9 +134,7 @@ ENTRY(__hyp_stub_install_secondary) | |||
| 134 | mcr p15, 4, r7, c1, c1, 3 @ HSTR | 134 | mcr p15, 4, r7, c1, c1, 3 @ HSTR |
| 135 | 135 | ||
| 136 | THUMB( orr r7, #(1 << 30) ) @ HSCTLR.TE | 136 | THUMB( orr r7, #(1 << 30) ) @ HSCTLR.TE |
| 137 | #ifdef CONFIG_CPU_BIG_ENDIAN | 137 | ARM_BE8(orr r7, r7, #(1 << 25)) @ HSCTLR.EE |
| 138 | orr r7, #(1 << 9) @ HSCTLR.EE | ||
| 139 | #endif | ||
| 140 | mcr p15, 4, r7, c1, c0, 0 @ HSCTLR | 138 | mcr p15, 4, r7, c1, c0, 0 @ HSCTLR |
| 141 | 139 | ||
| 142 | mrc p15, 4, r7, c1, c1, 1 @ HDCR | 140 | mrc p15, 4, r7, c1, c1, 1 @ HDCR |
diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig index 4be5bb150bdd..466bd299b1a8 100644 --- a/arch/arm/kvm/Kconfig +++ b/arch/arm/kvm/Kconfig | |||
| @@ -23,7 +23,7 @@ config KVM | |||
| 23 | select HAVE_KVM_CPU_RELAX_INTERCEPT | 23 | select HAVE_KVM_CPU_RELAX_INTERCEPT |
| 24 | select KVM_MMIO | 24 | select KVM_MMIO |
| 25 | select KVM_ARM_HOST | 25 | select KVM_ARM_HOST |
| 26 | depends on ARM_VIRT_EXT && ARM_LPAE && !CPU_BIG_ENDIAN | 26 | depends on ARM_VIRT_EXT && ARM_LPAE |
| 27 | ---help--- | 27 | ---help--- |
| 28 | Support hosting virtualized guest machines. You will also | 28 | Support hosting virtualized guest machines. You will also |
| 29 | need to select one or more of the processor modules below. | 29 | need to select one or more of the processor modules below. |
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile index 789bca9e64a7..f7057ed045b6 100644 --- a/arch/arm/kvm/Makefile +++ b/arch/arm/kvm/Makefile | |||
| @@ -21,4 +21,5 @@ obj-y += kvm-arm.o init.o interrupts.o | |||
| 21 | obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o | 21 | obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o |
| 22 | obj-y += coproc.o coproc_a15.o coproc_a7.o mmio.o psci.o perf.o | 22 | obj-y += coproc.o coproc_a15.o coproc_a7.o mmio.o psci.o perf.o |
| 23 | obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic.o | 23 | obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic.o |
| 24 | obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v2.o | ||
| 24 | obj-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o | 25 | obj-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o |
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 3c82b37c0f9e..a99e0cdf8ba2 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c | |||
| @@ -155,16 +155,6 @@ int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf) | |||
| 155 | return VM_FAULT_SIGBUS; | 155 | return VM_FAULT_SIGBUS; |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, | ||
| 159 | struct kvm_memory_slot *dont) | ||
| 160 | { | ||
| 161 | } | ||
| 162 | |||
| 163 | int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, | ||
| 164 | unsigned long npages) | ||
| 165 | { | ||
| 166 | return 0; | ||
| 167 | } | ||
| 168 | 158 | ||
| 169 | /** | 159 | /** |
| 170 | * kvm_arch_destroy_vm - destroy the VM data structure | 160 | * kvm_arch_destroy_vm - destroy the VM data structure |
| @@ -184,7 +174,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm) | |||
| 184 | } | 174 | } |
| 185 | } | 175 | } |
| 186 | 176 | ||
| 187 | int kvm_dev_ioctl_check_extension(long ext) | 177 | int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) |
| 188 | { | 178 | { |
| 189 | int r; | 179 | int r; |
| 190 | switch (ext) { | 180 | switch (ext) { |
| @@ -225,33 +215,6 @@ long kvm_arch_dev_ioctl(struct file *filp, | |||
| 225 | return -EINVAL; | 215 | return -EINVAL; |
| 226 | } | 216 | } |
| 227 | 217 | ||
| 228 | void kvm_arch_memslots_updated(struct kvm *kvm) | ||
| 229 | { | ||
| 230 | } | ||
| 231 | |||
| 232 | int kvm_arch_prepare_memory_region(struct kvm *kvm, | ||
| 233 | struct kvm_memory_slot *memslot, | ||
| 234 | struct kvm_userspace_memory_region *mem, | ||
| 235 | enum kvm_mr_change change) | ||
| 236 | { | ||
| 237 | return 0; | ||
| 238 | } | ||
| 239 | |||
| 240 | void kvm_arch_commit_memory_region(struct kvm *kvm, | ||
| 241 | struct kvm_userspace_memory_region *mem, | ||
| 242 | const struct kvm_memory_slot *old, | ||
| 243 | enum kvm_mr_change change) | ||
| 244 | { | ||
| 245 | } | ||
| 246 | |||
| 247 | void kvm_arch_flush_shadow_all(struct kvm *kvm) | ||
| 248 | { | ||
| 249 | } | ||
| 250 | |||
| 251 | void kvm_arch_flush_shadow_memslot(struct kvm *kvm, | ||
| 252 | struct kvm_memory_slot *slot) | ||
| 253 | { | ||
| 254 | } | ||
| 255 | 218 | ||
| 256 | struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) | 219 | struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) |
| 257 | { | 220 | { |
diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c index c58a35116f63..37a0fe1bb9bb 100644 --- a/arch/arm/kvm/coproc.c +++ b/arch/arm/kvm/coproc.c | |||
| @@ -44,6 +44,31 @@ static u32 cache_levels; | |||
| 44 | /* CSSELR values; used to index KVM_REG_ARM_DEMUX_ID_CCSIDR */ | 44 | /* CSSELR values; used to index KVM_REG_ARM_DEMUX_ID_CCSIDR */ |
| 45 | #define CSSELR_MAX 12 | 45 | #define CSSELR_MAX 12 |
| 46 | 46 | ||
| 47 | /* | ||
| 48 | * kvm_vcpu_arch.cp15 holds cp15 registers as an array of u32, but some | ||
| 49 | * of cp15 registers can be viewed either as couple of two u32 registers | ||
| 50 | * or one u64 register. Current u64 register encoding is that least | ||
| 51 | * significant u32 word is followed by most significant u32 word. | ||
| 52 | */ | ||
| 53 | static inline void vcpu_cp15_reg64_set(struct kvm_vcpu *vcpu, | ||
| 54 | const struct coproc_reg *r, | ||
| 55 | u64 val) | ||
| 56 | { | ||
| 57 | vcpu->arch.cp15[r->reg] = val & 0xffffffff; | ||
| 58 | vcpu->arch.cp15[r->reg + 1] = val >> 32; | ||
| 59 | } | ||
| 60 | |||
| 61 | static inline u64 vcpu_cp15_reg64_get(struct kvm_vcpu *vcpu, | ||
| 62 | const struct coproc_reg *r) | ||
| 63 | { | ||
| 64 | u64 val; | ||
| 65 | |||
| 66 | val = vcpu->arch.cp15[r->reg + 1]; | ||
| 67 | val = val << 32; | ||
| 68 | val = val | vcpu->arch.cp15[r->reg]; | ||
| 69 | return val; | ||
| 70 | } | ||
| 71 | |||
| 47 | int kvm_handle_cp10_id(struct kvm_vcpu *vcpu, struct kvm_run *run) | 72 | int kvm_handle_cp10_id(struct kvm_vcpu *vcpu, struct kvm_run *run) |
| 48 | { | 73 | { |
| 49 | kvm_inject_undefined(vcpu); | 74 | kvm_inject_undefined(vcpu); |
| @@ -682,17 +707,23 @@ static struct coproc_reg invariant_cp15[] = { | |||
| 682 | { CRn( 0), CRm( 0), Op1( 1), Op2( 7), is32, NULL, get_AIDR }, | 707 | { CRn( 0), CRm( 0), Op1( 1), Op2( 7), is32, NULL, get_AIDR }, |
| 683 | }; | 708 | }; |
| 684 | 709 | ||
| 710 | /* | ||
| 711 | * Reads a register value from a userspace address to a kernel | ||
| 712 | * variable. Make sure that register size matches sizeof(*__val). | ||
| 713 | */ | ||
| 685 | static int reg_from_user(void *val, const void __user *uaddr, u64 id) | 714 | static int reg_from_user(void *val, const void __user *uaddr, u64 id) |
| 686 | { | 715 | { |
| 687 | /* This Just Works because we are little endian. */ | ||
| 688 | if (copy_from_user(val, uaddr, KVM_REG_SIZE(id)) != 0) | 716 | if (copy_from_user(val, uaddr, KVM_REG_SIZE(id)) != 0) |
| 689 | return -EFAULT; | 717 | return -EFAULT; |
| 690 | return 0; | 718 | return 0; |
| 691 | } | 719 | } |
| 692 | 720 | ||
| 721 | /* | ||
| 722 | * Writes a register value to a userspace address from a kernel variable. | ||
| 723 | * Make sure that register size matches sizeof(*__val). | ||
| 724 | */ | ||
| 693 | static int reg_to_user(void __user *uaddr, const void *val, u64 id) | 725 | static int reg_to_user(void __user *uaddr, const void *val, u64 id) |
| 694 | { | 726 | { |
| 695 | /* This Just Works because we are little endian. */ | ||
| 696 | if (copy_to_user(uaddr, val, KVM_REG_SIZE(id)) != 0) | 727 | if (copy_to_user(uaddr, val, KVM_REG_SIZE(id)) != 0) |
| 697 | return -EFAULT; | 728 | return -EFAULT; |
| 698 | return 0; | 729 | return 0; |
| @@ -702,6 +733,7 @@ static int get_invariant_cp15(u64 id, void __user *uaddr) | |||
| 702 | { | 733 | { |
| 703 | struct coproc_params params; | 734 | struct coproc_params params; |
| 704 | const struct coproc_reg *r; | 735 | const struct coproc_reg *r; |
| 736 | int ret; | ||
| 705 | 737 | ||
| 706 | if (!index_to_params(id, ¶ms)) | 738 | if (!index_to_params(id, ¶ms)) |
| 707 | return -ENOENT; | 739 | return -ENOENT; |
| @@ -710,7 +742,15 @@ static int get_invariant_cp15(u64 id, void __user *uaddr) | |||
| 710 | if (!r) | 742 | if (!r) |
| 711 | return -ENOENT; | 743 | return -ENOENT; |
| 712 | 744 | ||
| 713 | return reg_to_user(uaddr, &r->val, id); | 745 | ret = -ENOENT; |
| 746 | if (KVM_REG_SIZE(id) == 4) { | ||
| 747 | u32 val = r->val; | ||
| 748 | |||
| 749 | ret = reg_to_user(uaddr, &val, id); | ||
| 750 | } else if (KVM_REG_SIZE(id) == 8) { | ||
| 751 | ret = reg_to_user(uaddr, &r->val, id); | ||
| 752 | } | ||
| 753 | return ret; | ||
| 714 | } | 754 | } |
| 715 | 755 | ||
| 716 | static int set_invariant_cp15(u64 id, void __user *uaddr) | 756 | static int set_invariant_cp15(u64 id, void __user *uaddr) |
| @@ -718,7 +758,7 @@ static int set_invariant_cp15(u64 id, void __user *uaddr) | |||
| 718 | struct coproc_params params; | 758 | struct coproc_params params; |
| 719 | const struct coproc_reg *r; | 759 | const struct coproc_reg *r; |
| 720 | int err; | 760 | int err; |
| 721 | u64 val = 0; /* Make sure high bits are 0 for 32-bit regs */ | 761 | u64 val; |
| 722 | 762 | ||
| 723 | if (!index_to_params(id, ¶ms)) | 763 | if (!index_to_params(id, ¶ms)) |
| 724 | return -ENOENT; | 764 | return -ENOENT; |
| @@ -726,7 +766,16 @@ static int set_invariant_cp15(u64 id, void __user *uaddr) | |||
| 726 | if (!r) | 766 | if (!r) |
| 727 | return -ENOENT; | 767 | return -ENOENT; |
| 728 | 768 | ||
| 729 | err = reg_from_user(&val, uaddr, id); | 769 | err = -ENOENT; |
| 770 | if (KVM_REG_SIZE(id) == 4) { | ||
| 771 | u32 val32; | ||
| 772 | |||
| 773 | err = reg_from_user(&val32, uaddr, id); | ||
| 774 | if (!err) | ||
| 775 | val = val32; | ||
| 776 | } else if (KVM_REG_SIZE(id) == 8) { | ||
| 777 | err = reg_from_user(&val, uaddr, id); | ||
| 778 | } | ||
| 730 | if (err) | 779 | if (err) |
| 731 | return err; | 780 | return err; |
| 732 | 781 | ||
| @@ -1004,6 +1053,7 @@ int kvm_arm_coproc_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | |||
| 1004 | { | 1053 | { |
| 1005 | const struct coproc_reg *r; | 1054 | const struct coproc_reg *r; |
| 1006 | void __user *uaddr = (void __user *)(long)reg->addr; | 1055 | void __user *uaddr = (void __user *)(long)reg->addr; |
| 1056 | int ret; | ||
| 1007 | 1057 | ||
| 1008 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_DEMUX) | 1058 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_DEMUX) |
| 1009 | return demux_c15_get(reg->id, uaddr); | 1059 | return demux_c15_get(reg->id, uaddr); |
| @@ -1015,14 +1065,24 @@ int kvm_arm_coproc_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | |||
| 1015 | if (!r) | 1065 | if (!r) |
| 1016 | return get_invariant_cp15(reg->id, uaddr); | 1066 | return get_invariant_cp15(reg->id, uaddr); |
| 1017 | 1067 | ||
| 1018 | /* Note: copies two regs if size is 64 bit. */ | 1068 | ret = -ENOENT; |
| 1019 | return reg_to_user(uaddr, &vcpu->arch.cp15[r->reg], reg->id); | 1069 | if (KVM_REG_SIZE(reg->id) == 8) { |
| 1070 | u64 val; | ||
| 1071 | |||
| 1072 | val = vcpu_cp15_reg64_get(vcpu, r); | ||
| 1073 | ret = reg_to_user(uaddr, &val, reg->id); | ||
| 1074 | } else if (KVM_REG_SIZE(reg->id) == 4) { | ||
| 1075 | ret = reg_to_user(uaddr, &vcpu->arch.cp15[r->reg], reg->id); | ||
| 1076 | } | ||
| 1077 | |||
| 1078 | return ret; | ||
| 1020 | } | 1079 | } |
| 1021 | 1080 | ||
| 1022 | int kvm_arm_coproc_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | 1081 | int kvm_arm_coproc_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) |
| 1023 | { | 1082 | { |
| 1024 | const struct coproc_reg *r; | 1083 | const struct coproc_reg *r; |
| 1025 | void __user *uaddr = (void __user *)(long)reg->addr; | 1084 | void __user *uaddr = (void __user *)(long)reg->addr; |
| 1085 | int ret; | ||
| 1026 | 1086 | ||
| 1027 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_DEMUX) | 1087 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_DEMUX) |
| 1028 | return demux_c15_set(reg->id, uaddr); | 1088 | return demux_c15_set(reg->id, uaddr); |
| @@ -1034,8 +1094,18 @@ int kvm_arm_coproc_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | |||
| 1034 | if (!r) | 1094 | if (!r) |
| 1035 | return set_invariant_cp15(reg->id, uaddr); | 1095 | return set_invariant_cp15(reg->id, uaddr); |
| 1036 | 1096 | ||
| 1037 | /* Note: copies two regs if size is 64 bit */ | 1097 | ret = -ENOENT; |
| 1038 | return reg_from_user(&vcpu->arch.cp15[r->reg], uaddr, reg->id); | 1098 | if (KVM_REG_SIZE(reg->id) == 8) { |
| 1099 | u64 val; | ||
| 1100 | |||
| 1101 | ret = reg_from_user(&val, uaddr, reg->id); | ||
| 1102 | if (!ret) | ||
| 1103 | vcpu_cp15_reg64_set(vcpu, r, val); | ||
| 1104 | } else if (KVM_REG_SIZE(reg->id) == 4) { | ||
| 1105 | ret = reg_from_user(&vcpu->arch.cp15[r->reg], uaddr, reg->id); | ||
| 1106 | } | ||
| 1107 | |||
| 1108 | return ret; | ||
| 1039 | } | 1109 | } |
| 1040 | 1110 | ||
| 1041 | static unsigned int num_demux_regs(void) | 1111 | static unsigned int num_demux_regs(void) |
diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c index 70bf49b8b244..813e49258690 100644 --- a/arch/arm/kvm/guest.c +++ b/arch/arm/kvm/guest.c | |||
| @@ -124,16 +124,6 @@ static bool is_timer_reg(u64 index) | |||
| 124 | return false; | 124 | return false; |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value) | ||
| 128 | { | ||
| 129 | return 0; | ||
| 130 | } | ||
| 131 | |||
| 132 | u64 kvm_arm_timer_get_reg(struct kvm_vcpu *vcpu, u64 regid) | ||
| 133 | { | ||
| 134 | return 0; | ||
| 135 | } | ||
| 136 | |||
| 137 | #else | 127 | #else |
| 138 | 128 | ||
| 139 | #define NUM_TIMER_REGS 3 | 129 | #define NUM_TIMER_REGS 3 |
diff --git a/arch/arm/kvm/init.S b/arch/arm/kvm/init.S index b2d229f09c07..991415d978b6 100644 --- a/arch/arm/kvm/init.S +++ b/arch/arm/kvm/init.S | |||
| @@ -72,7 +72,7 @@ __do_hyp_init: | |||
| 72 | bne phase2 @ Yes, second stage init | 72 | bne phase2 @ Yes, second stage init |
| 73 | 73 | ||
| 74 | @ Set the HTTBR to point to the hypervisor PGD pointer passed | 74 | @ Set the HTTBR to point to the hypervisor PGD pointer passed |
| 75 | mcrr p15, 4, r2, r3, c2 | 75 | mcrr p15, 4, rr_lo_hi(r2, r3), c2 |
| 76 | 76 | ||
| 77 | @ Set the HTCR and VTCR to the same shareability and cacheability | 77 | @ Set the HTCR and VTCR to the same shareability and cacheability |
| 78 | @ settings as the non-secure TTBCR and with T0SZ == 0. | 78 | @ settings as the non-secure TTBCR and with T0SZ == 0. |
| @@ -138,7 +138,7 @@ phase2: | |||
| 138 | ret r0 | 138 | ret r0 |
| 139 | 139 | ||
| 140 | target: @ We're now in the trampoline code, switch page tables | 140 | target: @ We're now in the trampoline code, switch page tables |
| 141 | mcrr p15, 4, r2, r3, c2 | 141 | mcrr p15, 4, rr_lo_hi(r2, r3), c2 |
| 142 | isb | 142 | isb |
| 143 | 143 | ||
| 144 | @ Invalidate the old TLBs | 144 | @ Invalidate the old TLBs |
diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S index 0d68d4073068..01dcb0e752d9 100644 --- a/arch/arm/kvm/interrupts.S +++ b/arch/arm/kvm/interrupts.S | |||
| @@ -52,7 +52,7 @@ ENTRY(__kvm_tlb_flush_vmid_ipa) | |||
| 52 | dsb ishst | 52 | dsb ishst |
| 53 | add r0, r0, #KVM_VTTBR | 53 | add r0, r0, #KVM_VTTBR |
| 54 | ldrd r2, r3, [r0] | 54 | ldrd r2, r3, [r0] |
| 55 | mcrr p15, 6, r2, r3, c2 @ Write VTTBR | 55 | mcrr p15, 6, rr_lo_hi(r2, r3), c2 @ Write VTTBR |
| 56 | isb | 56 | isb |
| 57 | mcr p15, 0, r0, c8, c3, 0 @ TLBIALLIS (rt ignored) | 57 | mcr p15, 0, r0, c8, c3, 0 @ TLBIALLIS (rt ignored) |
| 58 | dsb ish | 58 | dsb ish |
| @@ -135,7 +135,7 @@ ENTRY(__kvm_vcpu_run) | |||
| 135 | ldr r1, [vcpu, #VCPU_KVM] | 135 | ldr r1, [vcpu, #VCPU_KVM] |
| 136 | add r1, r1, #KVM_VTTBR | 136 | add r1, r1, #KVM_VTTBR |
| 137 | ldrd r2, r3, [r1] | 137 | ldrd r2, r3, [r1] |
| 138 | mcrr p15, 6, r2, r3, c2 @ Write VTTBR | 138 | mcrr p15, 6, rr_lo_hi(r2, r3), c2 @ Write VTTBR |
| 139 | 139 | ||
| 140 | @ We're all done, just restore the GPRs and go to the guest | 140 | @ We're all done, just restore the GPRs and go to the guest |
| 141 | restore_guest_regs | 141 | restore_guest_regs |
| @@ -199,8 +199,13 @@ after_vfp_restore: | |||
| 199 | 199 | ||
| 200 | restore_host_regs | 200 | restore_host_regs |
| 201 | clrex @ Clear exclusive monitor | 201 | clrex @ Clear exclusive monitor |
| 202 | #ifndef CONFIG_CPU_ENDIAN_BE8 | ||
| 202 | mov r0, r1 @ Return the return code | 203 | mov r0, r1 @ Return the return code |
| 203 | mov r1, #0 @ Clear upper bits in return value | 204 | mov r1, #0 @ Clear upper bits in return value |
| 205 | #else | ||
| 206 | @ r1 already has return code | ||
| 207 | mov r0, #0 @ Clear upper bits in return value | ||
| 208 | #endif /* CONFIG_CPU_ENDIAN_BE8 */ | ||
| 204 | bx lr @ return to IOCTL | 209 | bx lr @ return to IOCTL |
| 205 | 210 | ||
| 206 | /******************************************************************** | 211 | /******************************************************************** |
diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S index 76af93025574..98c8c5b9a87f 100644 --- a/arch/arm/kvm/interrupts_head.S +++ b/arch/arm/kvm/interrupts_head.S | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | #include <linux/irqchip/arm-gic.h> | 1 | #include <linux/irqchip/arm-gic.h> |
| 2 | #include <asm/assembler.h> | ||
| 2 | 3 | ||
| 3 | #define VCPU_USR_REG(_reg_nr) (VCPU_USR_REGS + (_reg_nr * 4)) | 4 | #define VCPU_USR_REG(_reg_nr) (VCPU_USR_REGS + (_reg_nr * 4)) |
| 4 | #define VCPU_USR_SP (VCPU_USR_REG(13)) | 5 | #define VCPU_USR_SP (VCPU_USR_REG(13)) |
| @@ -420,15 +421,23 @@ vcpu .req r0 @ vcpu pointer always in r0 | |||
| 420 | ldr r8, [r2, #GICH_ELRSR0] | 421 | ldr r8, [r2, #GICH_ELRSR0] |
| 421 | ldr r9, [r2, #GICH_ELRSR1] | 422 | ldr r9, [r2, #GICH_ELRSR1] |
| 422 | ldr r10, [r2, #GICH_APR] | 423 | ldr r10, [r2, #GICH_APR] |
| 423 | 424 | ARM_BE8(rev r3, r3 ) | |
| 424 | str r3, [r11, #VGIC_CPU_HCR] | 425 | ARM_BE8(rev r4, r4 ) |
| 425 | str r4, [r11, #VGIC_CPU_VMCR] | 426 | ARM_BE8(rev r5, r5 ) |
| 426 | str r5, [r11, #VGIC_CPU_MISR] | 427 | ARM_BE8(rev r6, r6 ) |
| 427 | str r6, [r11, #VGIC_CPU_EISR] | 428 | ARM_BE8(rev r7, r7 ) |
| 428 | str r7, [r11, #(VGIC_CPU_EISR + 4)] | 429 | ARM_BE8(rev r8, r8 ) |
| 429 | str r8, [r11, #VGIC_CPU_ELRSR] | 430 | ARM_BE8(rev r9, r9 ) |
| 430 | str r9, [r11, #(VGIC_CPU_ELRSR + 4)] | 431 | ARM_BE8(rev r10, r10 ) |
| 431 | str r10, [r11, #VGIC_CPU_APR] | 432 | |
| 433 | str r3, [r11, #VGIC_V2_CPU_HCR] | ||
| 434 | str r4, [r11, #VGIC_V2_CPU_VMCR] | ||
| 435 | str r5, [r11, #VGIC_V2_CPU_MISR] | ||
| 436 | str r6, [r11, #VGIC_V2_CPU_EISR] | ||
| 437 | str r7, [r11, #(VGIC_V2_CPU_EISR + 4)] | ||
| 438 | str r8, [r11, #VGIC_V2_CPU_ELRSR] | ||
| 439 | str r9, [r11, #(VGIC_V2_CPU_ELRSR + 4)] | ||
| 440 | str r10, [r11, #VGIC_V2_CPU_APR] | ||
| 432 | 441 | ||
| 433 | /* Clear GICH_HCR */ | 442 | /* Clear GICH_HCR */ |
| 434 | mov r5, #0 | 443 | mov r5, #0 |
| @@ -436,9 +445,10 @@ vcpu .req r0 @ vcpu pointer always in r0 | |||
| 436 | 445 | ||
| 437 | /* Save list registers */ | 446 | /* Save list registers */ |
| 438 | add r2, r2, #GICH_LR0 | 447 | add r2, r2, #GICH_LR0 |
| 439 | add r3, r11, #VGIC_CPU_LR | 448 | add r3, r11, #VGIC_V2_CPU_LR |
| 440 | ldr r4, [r11, #VGIC_CPU_NR_LR] | 449 | ldr r4, [r11, #VGIC_CPU_NR_LR] |
| 441 | 1: ldr r6, [r2], #4 | 450 | 1: ldr r6, [r2], #4 |
| 451 | ARM_BE8(rev r6, r6 ) | ||
| 442 | str r6, [r3], #4 | 452 | str r6, [r3], #4 |
| 443 | subs r4, r4, #1 | 453 | subs r4, r4, #1 |
| 444 | bne 1b | 454 | bne 1b |
| @@ -463,9 +473,12 @@ vcpu .req r0 @ vcpu pointer always in r0 | |||
| 463 | add r11, vcpu, #VCPU_VGIC_CPU | 473 | add r11, vcpu, #VCPU_VGIC_CPU |
| 464 | 474 | ||
| 465 | /* We only restore a minimal set of registers */ | 475 | /* We only restore a minimal set of registers */ |
| 466 | ldr r3, [r11, #VGIC_CPU_HCR] | 476 | ldr r3, [r11, #VGIC_V2_CPU_HCR] |
| 467 | ldr r4, [r11, #VGIC_CPU_VMCR] | 477 | ldr r4, [r11, #VGIC_V2_CPU_VMCR] |
| 468 | ldr r8, [r11, #VGIC_CPU_APR] | 478 | ldr r8, [r11, #VGIC_V2_CPU_APR] |
| 479 | ARM_BE8(rev r3, r3 ) | ||
| 480 | ARM_BE8(rev r4, r4 ) | ||
| 481 | ARM_BE8(rev r8, r8 ) | ||
| 469 | 482 | ||
| 470 | str r3, [r2, #GICH_HCR] | 483 | str r3, [r2, #GICH_HCR] |
| 471 | str r4, [r2, #GICH_VMCR] | 484 | str r4, [r2, #GICH_VMCR] |
| @@ -473,9 +486,10 @@ vcpu .req r0 @ vcpu pointer always in r0 | |||
| 473 | 486 | ||
| 474 | /* Restore list registers */ | 487 | /* Restore list registers */ |
| 475 | add r2, r2, #GICH_LR0 | 488 | add r2, r2, #GICH_LR0 |
| 476 | add r3, r11, #VGIC_CPU_LR | 489 | add r3, r11, #VGIC_V2_CPU_LR |
| 477 | ldr r4, [r11, #VGIC_CPU_NR_LR] | 490 | ldr r4, [r11, #VGIC_CPU_NR_LR] |
| 478 | 1: ldr r6, [r3], #4 | 491 | 1: ldr r6, [r3], #4 |
| 492 | ARM_BE8(rev r6, r6 ) | ||
| 479 | str r6, [r2], #4 | 493 | str r6, [r2], #4 |
| 480 | subs r4, r4, #1 | 494 | subs r4, r4, #1 |
| 481 | bne 1b | 495 | bne 1b |
| @@ -506,7 +520,7 @@ vcpu .req r0 @ vcpu pointer always in r0 | |||
| 506 | mcr p15, 0, r2, c14, c3, 1 @ CNTV_CTL | 520 | mcr p15, 0, r2, c14, c3, 1 @ CNTV_CTL |
| 507 | isb | 521 | isb |
| 508 | 522 | ||
| 509 | mrrc p15, 3, r2, r3, c14 @ CNTV_CVAL | 523 | mrrc p15, 3, rr_lo_hi(r2, r3), c14 @ CNTV_CVAL |
| 510 | ldr r4, =VCPU_TIMER_CNTV_CVAL | 524 | ldr r4, =VCPU_TIMER_CNTV_CVAL |
| 511 | add r5, vcpu, r4 | 525 | add r5, vcpu, r4 |
| 512 | strd r2, r3, [r5] | 526 | strd r2, r3, [r5] |
| @@ -546,12 +560,12 @@ vcpu .req r0 @ vcpu pointer always in r0 | |||
| 546 | 560 | ||
| 547 | ldr r2, [r4, #KVM_TIMER_CNTVOFF] | 561 | ldr r2, [r4, #KVM_TIMER_CNTVOFF] |
| 548 | ldr r3, [r4, #(KVM_TIMER_CNTVOFF + 4)] | 562 | ldr r3, [r4, #(KVM_TIMER_CNTVOFF + 4)] |
| 549 | mcrr p15, 4, r2, r3, c14 @ CNTVOFF | 563 | mcrr p15, 4, rr_lo_hi(r2, r3), c14 @ CNTVOFF |
| 550 | 564 | ||
| 551 | ldr r4, =VCPU_TIMER_CNTV_CVAL | 565 | ldr r4, =VCPU_TIMER_CNTV_CVAL |
| 552 | add r5, vcpu, r4 | 566 | add r5, vcpu, r4 |
| 553 | ldrd r2, r3, [r5] | 567 | ldrd r2, r3, [r5] |
| 554 | mcrr p15, 3, r2, r3, c14 @ CNTV_CVAL | 568 | mcrr p15, 3, rr_lo_hi(r2, r3), c14 @ CNTV_CVAL |
| 555 | isb | 569 | isb |
| 556 | 570 | ||
| 557 | ldr r2, [vcpu, #VCPU_TIMER_CNTV_CTL] | 571 | ldr r2, [vcpu, #VCPU_TIMER_CNTV_CTL] |
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 16f804938b8f..16e7994bf347 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c | |||
| @@ -90,104 +90,115 @@ static void *mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc) | |||
| 90 | return p; | 90 | return p; |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | static bool page_empty(void *ptr) | 93 | static void clear_pgd_entry(struct kvm *kvm, pgd_t *pgd, phys_addr_t addr) |
| 94 | { | 94 | { |
| 95 | struct page *ptr_page = virt_to_page(ptr); | 95 | pud_t *pud_table __maybe_unused = pud_offset(pgd, 0); |
| 96 | return page_count(ptr_page) == 1; | 96 | pgd_clear(pgd); |
| 97 | kvm_tlb_flush_vmid_ipa(kvm, addr); | ||
| 98 | pud_free(NULL, pud_table); | ||
| 99 | put_page(virt_to_page(pgd)); | ||
| 97 | } | 100 | } |
| 98 | 101 | ||
| 99 | static void clear_pud_entry(struct kvm *kvm, pud_t *pud, phys_addr_t addr) | 102 | static void clear_pud_entry(struct kvm *kvm, pud_t *pud, phys_addr_t addr) |
| 100 | { | 103 | { |
| 101 | if (pud_huge(*pud)) { | 104 | pmd_t *pmd_table = pmd_offset(pud, 0); |
| 102 | pud_clear(pud); | 105 | VM_BUG_ON(pud_huge(*pud)); |
| 103 | kvm_tlb_flush_vmid_ipa(kvm, addr); | 106 | pud_clear(pud); |
| 104 | } else { | 107 | kvm_tlb_flush_vmid_ipa(kvm, addr); |
| 105 | pmd_t *pmd_table = pmd_offset(pud, 0); | 108 | pmd_free(NULL, pmd_table); |
| 106 | pud_clear(pud); | ||
| 107 | kvm_tlb_flush_vmid_ipa(kvm, addr); | ||
| 108 | pmd_free(NULL, pmd_table); | ||
| 109 | } | ||
| 110 | put_page(virt_to_page(pud)); | 109 | put_page(virt_to_page(pud)); |
| 111 | } | 110 | } |
| 112 | 111 | ||
| 113 | static void clear_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr) | 112 | static void clear_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr) |
| 114 | { | 113 | { |
| 115 | if (kvm_pmd_huge(*pmd)) { | 114 | pte_t *pte_table = pte_offset_kernel(pmd, 0); |
| 116 | pmd_clear(pmd); | 115 | VM_BUG_ON(kvm_pmd_huge(*pmd)); |
| 117 | kvm_tlb_flush_vmid_ipa(kvm, addr); | 116 | pmd_clear(pmd); |
| 118 | } else { | 117 | kvm_tlb_flush_vmid_ipa(kvm, addr); |
| 119 | pte_t *pte_table = pte_offset_kernel(pmd, 0); | 118 | pte_free_kernel(NULL, pte_table); |
| 120 | pmd_clear(pmd); | ||
| 121 | kvm_tlb_flush_vmid_ipa(kvm, addr); | ||
| 122 | pte_free_kernel(NULL, pte_table); | ||
| 123 | } | ||
| 124 | put_page(virt_to_page(pmd)); | 119 | put_page(virt_to_page(pmd)); |
| 125 | } | 120 | } |
| 126 | 121 | ||
| 127 | static void clear_pte_entry(struct kvm *kvm, pte_t *pte, phys_addr_t addr) | 122 | static void unmap_ptes(struct kvm *kvm, pmd_t *pmd, |
| 123 | phys_addr_t addr, phys_addr_t end) | ||
| 128 | { | 124 | { |
| 129 | if (pte_present(*pte)) { | 125 | phys_addr_t start_addr = addr; |
| 130 | kvm_set_pte(pte, __pte(0)); | 126 | pte_t *pte, *start_pte; |
| 131 | put_page(virt_to_page(pte)); | 127 | |
| 132 | kvm_tlb_flush_vmid_ipa(kvm, addr); | 128 | start_pte = pte = pte_offset_kernel(pmd, addr); |
| 133 | } | 129 | do { |
| 130 | if (!pte_none(*pte)) { | ||
| 131 | kvm_set_pte(pte, __pte(0)); | ||
| 132 | put_page(virt_to_page(pte)); | ||
| 133 | kvm_tlb_flush_vmid_ipa(kvm, addr); | ||
| 134 | } | ||
| 135 | } while (pte++, addr += PAGE_SIZE, addr != end); | ||
| 136 | |||
| 137 | if (kvm_pte_table_empty(start_pte)) | ||
| 138 | clear_pmd_entry(kvm, pmd, start_addr); | ||
| 134 | } | 139 | } |
| 135 | 140 | ||
| 136 | static void unmap_range(struct kvm *kvm, pgd_t *pgdp, | 141 | static void unmap_pmds(struct kvm *kvm, pud_t *pud, |
| 137 | unsigned long long start, u64 size) | 142 | phys_addr_t addr, phys_addr_t end) |
| 138 | { | 143 | { |
| 139 | pgd_t *pgd; | 144 | phys_addr_t next, start_addr = addr; |
| 140 | pud_t *pud; | 145 | pmd_t *pmd, *start_pmd; |
| 141 | pmd_t *pmd; | ||
| 142 | pte_t *pte; | ||
| 143 | unsigned long long addr = start, end = start + size; | ||
| 144 | u64 next; | ||
| 145 | |||
| 146 | while (addr < end) { | ||
| 147 | pgd = pgdp + pgd_index(addr); | ||
| 148 | pud = pud_offset(pgd, addr); | ||
| 149 | pte = NULL; | ||
| 150 | if (pud_none(*pud)) { | ||
| 151 | addr = kvm_pud_addr_end(addr, end); | ||
| 152 | continue; | ||
| 153 | } | ||
| 154 | 146 | ||
| 155 | if (pud_huge(*pud)) { | 147 | start_pmd = pmd = pmd_offset(pud, addr); |
| 156 | /* | 148 | do { |
| 157 | * If we are dealing with a huge pud, just clear it and | 149 | next = kvm_pmd_addr_end(addr, end); |
| 158 | * move on. | 150 | if (!pmd_none(*pmd)) { |
| 159 | */ | 151 | if (kvm_pmd_huge(*pmd)) { |
| 160 | clear_pud_entry(kvm, pud, addr); | 152 | pmd_clear(pmd); |
| 161 | addr = kvm_pud_addr_end(addr, end); | 153 | kvm_tlb_flush_vmid_ipa(kvm, addr); |
| 162 | continue; | 154 | put_page(virt_to_page(pmd)); |
| 155 | } else { | ||
| 156 | unmap_ptes(kvm, pmd, addr, next); | ||
| 157 | } | ||
| 163 | } | 158 | } |
| 159 | } while (pmd++, addr = next, addr != end); | ||
| 164 | 160 | ||
| 165 | pmd = pmd_offset(pud, addr); | 161 | if (kvm_pmd_table_empty(start_pmd)) |
| 166 | if (pmd_none(*pmd)) { | 162 | clear_pud_entry(kvm, pud, start_addr); |
| 167 | addr = kvm_pmd_addr_end(addr, end); | 163 | } |
| 168 | continue; | ||
| 169 | } | ||
| 170 | 164 | ||
| 171 | if (!kvm_pmd_huge(*pmd)) { | 165 | static void unmap_puds(struct kvm *kvm, pgd_t *pgd, |
| 172 | pte = pte_offset_kernel(pmd, addr); | 166 | phys_addr_t addr, phys_addr_t end) |
| 173 | clear_pte_entry(kvm, pte, addr); | 167 | { |
| 174 | next = addr + PAGE_SIZE; | 168 | phys_addr_t next, start_addr = addr; |
| 175 | } | 169 | pud_t *pud, *start_pud; |
| 176 | 170 | ||
| 177 | /* | 171 | start_pud = pud = pud_offset(pgd, addr); |
| 178 | * If the pmd entry is to be cleared, walk back up the ladder | 172 | do { |
| 179 | */ | 173 | next = kvm_pud_addr_end(addr, end); |
| 180 | if (kvm_pmd_huge(*pmd) || (pte && page_empty(pte))) { | 174 | if (!pud_none(*pud)) { |
| 181 | clear_pmd_entry(kvm, pmd, addr); | 175 | if (pud_huge(*pud)) { |
| 182 | next = kvm_pmd_addr_end(addr, end); | 176 | pud_clear(pud); |
| 183 | if (page_empty(pmd) && !page_empty(pud)) { | 177 | kvm_tlb_flush_vmid_ipa(kvm, addr); |
| 184 | clear_pud_entry(kvm, pud, addr); | 178 | put_page(virt_to_page(pud)); |
| 185 | next = kvm_pud_addr_end(addr, end); | 179 | } else { |
| 180 | unmap_pmds(kvm, pud, addr, next); | ||
| 186 | } | 181 | } |
| 187 | } | 182 | } |
| 183 | } while (pud++, addr = next, addr != end); | ||
| 188 | 184 | ||
| 189 | addr = next; | 185 | if (kvm_pud_table_empty(start_pud)) |
| 190 | } | 186 | clear_pgd_entry(kvm, pgd, start_addr); |
| 187 | } | ||
| 188 | |||
| 189 | |||
| 190 | static void unmap_range(struct kvm *kvm, pgd_t *pgdp, | ||
| 191 | phys_addr_t start, u64 size) | ||
| 192 | { | ||
| 193 | pgd_t *pgd; | ||
| 194 | phys_addr_t addr = start, end = start + size; | ||
| 195 | phys_addr_t next; | ||
| 196 | |||
| 197 | pgd = pgdp + pgd_index(addr); | ||
| 198 | do { | ||
| 199 | next = kvm_pgd_addr_end(addr, end); | ||
| 200 | unmap_puds(kvm, pgd, addr, next); | ||
| 201 | } while (pgd++, addr = next, addr != end); | ||
| 191 | } | 202 | } |
| 192 | 203 | ||
| 193 | static void stage2_flush_ptes(struct kvm *kvm, pmd_t *pmd, | 204 | static void stage2_flush_ptes(struct kvm *kvm, pmd_t *pmd, |
| @@ -748,6 +759,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
| 748 | struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache; | 759 | struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache; |
| 749 | struct vm_area_struct *vma; | 760 | struct vm_area_struct *vma; |
| 750 | pfn_t pfn; | 761 | pfn_t pfn; |
| 762 | pgprot_t mem_type = PAGE_S2; | ||
| 751 | 763 | ||
| 752 | write_fault = kvm_is_write_fault(kvm_vcpu_get_hsr(vcpu)); | 764 | write_fault = kvm_is_write_fault(kvm_vcpu_get_hsr(vcpu)); |
| 753 | if (fault_status == FSC_PERM && !write_fault) { | 765 | if (fault_status == FSC_PERM && !write_fault) { |
| @@ -798,6 +810,9 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
| 798 | if (is_error_pfn(pfn)) | 810 | if (is_error_pfn(pfn)) |
| 799 | return -EFAULT; | 811 | return -EFAULT; |
| 800 | 812 | ||
| 813 | if (kvm_is_mmio_pfn(pfn)) | ||
| 814 | mem_type = PAGE_S2_DEVICE; | ||
| 815 | |||
| 801 | spin_lock(&kvm->mmu_lock); | 816 | spin_lock(&kvm->mmu_lock); |
| 802 | if (mmu_notifier_retry(kvm, mmu_seq)) | 817 | if (mmu_notifier_retry(kvm, mmu_seq)) |
| 803 | goto out_unlock; | 818 | goto out_unlock; |
| @@ -805,7 +820,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
| 805 | hugetlb = transparent_hugepage_adjust(&pfn, &fault_ipa); | 820 | hugetlb = transparent_hugepage_adjust(&pfn, &fault_ipa); |
| 806 | 821 | ||
| 807 | if (hugetlb) { | 822 | if (hugetlb) { |
| 808 | pmd_t new_pmd = pfn_pmd(pfn, PAGE_S2); | 823 | pmd_t new_pmd = pfn_pmd(pfn, mem_type); |
| 809 | new_pmd = pmd_mkhuge(new_pmd); | 824 | new_pmd = pmd_mkhuge(new_pmd); |
| 810 | if (writable) { | 825 | if (writable) { |
| 811 | kvm_set_s2pmd_writable(&new_pmd); | 826 | kvm_set_s2pmd_writable(&new_pmd); |
| @@ -814,13 +829,14 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
| 814 | coherent_cache_guest_page(vcpu, hva & PMD_MASK, PMD_SIZE); | 829 | coherent_cache_guest_page(vcpu, hva & PMD_MASK, PMD_SIZE); |
| 815 | ret = stage2_set_pmd_huge(kvm, memcache, fault_ipa, &new_pmd); | 830 | ret = stage2_set_pmd_huge(kvm, memcache, fault_ipa, &new_pmd); |
| 816 | } else { | 831 | } else { |
| 817 | pte_t new_pte = pfn_pte(pfn, PAGE_S2); | 832 | pte_t new_pte = pfn_pte(pfn, mem_type); |
| 818 | if (writable) { | 833 | if (writable) { |
| 819 | kvm_set_s2pte_writable(&new_pte); | 834 | kvm_set_s2pte_writable(&new_pte); |
| 820 | kvm_set_pfn_dirty(pfn); | 835 | kvm_set_pfn_dirty(pfn); |
| 821 | } | 836 | } |
| 822 | coherent_cache_guest_page(vcpu, hva, PAGE_SIZE); | 837 | coherent_cache_guest_page(vcpu, hva, PAGE_SIZE); |
| 823 | ret = stage2_set_pte(kvm, memcache, fault_ipa, &new_pte, false); | 838 | ret = stage2_set_pte(kvm, memcache, fault_ipa, &new_pte, |
| 839 | mem_type == PAGE_S2_DEVICE); | ||
| 824 | } | 840 | } |
| 825 | 841 | ||
| 826 | 842 | ||
| @@ -1100,3 +1116,49 @@ out: | |||
| 1100 | free_hyp_pgds(); | 1116 | free_hyp_pgds(); |
| 1101 | return err; | 1117 | return err; |
| 1102 | } | 1118 | } |
| 1119 | |||
| 1120 | void kvm_arch_commit_memory_region(struct kvm *kvm, | ||
| 1121 | struct kvm_userspace_memory_region *mem, | ||
| 1122 | const struct kvm_memory_slot *old, | ||
| 1123 | enum kvm_mr_change change) | ||
| 1124 | { | ||
| 1125 | gpa_t gpa = old->base_gfn << PAGE_SHIFT; | ||
| 1126 | phys_addr_t size = old->npages << PAGE_SHIFT; | ||
| 1127 | if (change == KVM_MR_DELETE || change == KVM_MR_MOVE) { | ||
| 1128 | spin_lock(&kvm->mmu_lock); | ||
| 1129 | unmap_stage2_range(kvm, gpa, size); | ||
| 1130 | spin_unlock(&kvm->mmu_lock); | ||
| 1131 | } | ||
| 1132 | } | ||
| 1133 | |||
| 1134 | int kvm_arch_prepare_memory_region(struct kvm *kvm, | ||
| 1135 | struct kvm_memory_slot *memslot, | ||
| 1136 | struct kvm_userspace_memory_region *mem, | ||
| 1137 | enum kvm_mr_change change) | ||
| 1138 | { | ||
| 1139 | return 0; | ||
| 1140 | } | ||
| 1141 | |||
| 1142 | void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, | ||
| 1143 | struct kvm_memory_slot *dont) | ||
| 1144 | { | ||
| 1145 | } | ||
| 1146 | |||
| 1147 | int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, | ||
| 1148 | unsigned long npages) | ||
| 1149 | { | ||
| 1150 | return 0; | ||
| 1151 | } | ||
| 1152 | |||
| 1153 | void kvm_arch_memslots_updated(struct kvm *kvm) | ||
| 1154 | { | ||
| 1155 | } | ||
| 1156 | |||
| 1157 | void kvm_arch_flush_shadow_all(struct kvm *kvm) | ||
| 1158 | { | ||
| 1159 | } | ||
| 1160 | |||
| 1161 | void kvm_arch_flush_shadow_memslot(struct kvm *kvm, | ||
| 1162 | struct kvm_memory_slot *slot) | ||
| 1163 | { | ||
| 1164 | } | ||
diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h index 6e9b5b36921c..7fb343779498 100644 --- a/arch/arm64/include/asm/debug-monitors.h +++ b/arch/arm64/include/asm/debug-monitors.h | |||
| @@ -18,6 +18,15 @@ | |||
| 18 | 18 | ||
| 19 | #ifdef __KERNEL__ | 19 | #ifdef __KERNEL__ |
| 20 | 20 | ||
| 21 | /* Low-level stepping controls. */ | ||
| 22 | #define DBG_MDSCR_SS (1 << 0) | ||
| 23 | #define DBG_SPSR_SS (1 << 21) | ||
| 24 | |||
| 25 | /* MDSCR_EL1 enabling bits */ | ||
| 26 | #define DBG_MDSCR_KDE (1 << 13) | ||
| 27 | #define DBG_MDSCR_MDE (1 << 15) | ||
| 28 | #define DBG_MDSCR_MASK ~(DBG_MDSCR_KDE | DBG_MDSCR_MDE) | ||
| 29 | |||
| 21 | #define DBG_ESR_EVT(x) (((x) >> 27) & 0x7) | 30 | #define DBG_ESR_EVT(x) (((x) >> 27) & 0x7) |
| 22 | 31 | ||
| 23 | /* AArch64 */ | 32 | /* AArch64 */ |
| @@ -73,11 +82,6 @@ | |||
| 73 | 82 | ||
| 74 | #define CACHE_FLUSH_IS_SAFE 1 | 83 | #define CACHE_FLUSH_IS_SAFE 1 |
| 75 | 84 | ||
| 76 | enum debug_el { | ||
| 77 | DBG_ACTIVE_EL0 = 0, | ||
| 78 | DBG_ACTIVE_EL1, | ||
| 79 | }; | ||
| 80 | |||
| 81 | /* AArch32 */ | 85 | /* AArch32 */ |
| 82 | #define DBG_ESR_EVT_BKPT 0x4 | 86 | #define DBG_ESR_EVT_BKPT 0x4 |
| 83 | #define DBG_ESR_EVT_VECC 0x5 | 87 | #define DBG_ESR_EVT_VECC 0x5 |
| @@ -115,6 +119,11 @@ void unregister_break_hook(struct break_hook *hook); | |||
| 115 | 119 | ||
| 116 | u8 debug_monitors_arch(void); | 120 | u8 debug_monitors_arch(void); |
| 117 | 121 | ||
| 122 | enum debug_el { | ||
| 123 | DBG_ACTIVE_EL0 = 0, | ||
| 124 | DBG_ACTIVE_EL1, | ||
| 125 | }; | ||
| 126 | |||
| 118 | void enable_debug_monitors(enum debug_el el); | 127 | void enable_debug_monitors(enum debug_el el); |
| 119 | void disable_debug_monitors(enum debug_el el); | 128 | void disable_debug_monitors(enum debug_el el); |
| 120 | 129 | ||
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index 3d6903006a8a..cc83520459ed 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h | |||
| @@ -76,9 +76,10 @@ | |||
| 76 | */ | 76 | */ |
| 77 | #define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWE | HCR_TWI | HCR_VM | \ | 77 | #define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWE | HCR_TWI | HCR_VM | \ |
| 78 | HCR_TVM | HCR_BSU_IS | HCR_FB | HCR_TAC | \ | 78 | HCR_TVM | HCR_BSU_IS | HCR_FB | HCR_TAC | \ |
| 79 | HCR_AMO | HCR_IMO | HCR_FMO | \ | 79 | HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW) |
| 80 | HCR_SWIO | HCR_TIDCP | HCR_RW) | ||
| 81 | #define HCR_VIRT_EXCP_MASK (HCR_VA | HCR_VI | HCR_VF) | 80 | #define HCR_VIRT_EXCP_MASK (HCR_VA | HCR_VI | HCR_VF) |
| 81 | #define HCR_INT_OVERRIDE (HCR_FMO | HCR_IMO) | ||
| 82 | |||
| 82 | 83 | ||
| 83 | /* Hyp System Control Register (SCTLR_EL2) bits */ | 84 | /* Hyp System Control Register (SCTLR_EL2) bits */ |
| 84 | #define SCTLR_EL2_EE (1 << 25) | 85 | #define SCTLR_EL2_EE (1 << 25) |
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h index 9fcd54b1e16d..483842180f8f 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h | |||
| @@ -18,6 +18,8 @@ | |||
| 18 | #ifndef __ARM_KVM_ASM_H__ | 18 | #ifndef __ARM_KVM_ASM_H__ |
| 19 | #define __ARM_KVM_ASM_H__ | 19 | #define __ARM_KVM_ASM_H__ |
| 20 | 20 | ||
| 21 | #include <asm/virt.h> | ||
| 22 | |||
| 21 | /* | 23 | /* |
| 22 | * 0 is reserved as an invalid value. | 24 | * 0 is reserved as an invalid value. |
| 23 | * Order *must* be kept in sync with the hyp switch code. | 25 | * Order *must* be kept in sync with the hyp switch code. |
| @@ -43,14 +45,25 @@ | |||
| 43 | #define AMAIR_EL1 19 /* Aux Memory Attribute Indirection Register */ | 45 | #define AMAIR_EL1 19 /* Aux Memory Attribute Indirection Register */ |
| 44 | #define CNTKCTL_EL1 20 /* Timer Control Register (EL1) */ | 46 | #define CNTKCTL_EL1 20 /* Timer Control Register (EL1) */ |
| 45 | #define PAR_EL1 21 /* Physical Address Register */ | 47 | #define PAR_EL1 21 /* Physical Address Register */ |
| 48 | #define MDSCR_EL1 22 /* Monitor Debug System Control Register */ | ||
| 49 | #define DBGBCR0_EL1 23 /* Debug Breakpoint Control Registers (0-15) */ | ||
| 50 | #define DBGBCR15_EL1 38 | ||
| 51 | #define DBGBVR0_EL1 39 /* Debug Breakpoint Value Registers (0-15) */ | ||
| 52 | #define DBGBVR15_EL1 54 | ||
| 53 | #define DBGWCR0_EL1 55 /* Debug Watchpoint Control Registers (0-15) */ | ||
| 54 | #define DBGWCR15_EL1 70 | ||
| 55 | #define DBGWVR0_EL1 71 /* Debug Watchpoint Value Registers (0-15) */ | ||
| 56 | #define DBGWVR15_EL1 86 | ||
| 57 | #define MDCCINT_EL1 87 /* Monitor Debug Comms Channel Interrupt Enable Reg */ | ||
| 58 | |||
| 46 | /* 32bit specific registers. Keep them at the end of the range */ | 59 | /* 32bit specific registers. Keep them at the end of the range */ |
| 47 | #define DACR32_EL2 22 /* Domain Access Control Register */ | 60 | #define DACR32_EL2 88 /* Domain Access Control Register */ |
| 48 | #define IFSR32_EL2 23 /* Instruction Fault Status Register */ | 61 | #define IFSR32_EL2 89 /* Instruction Fault Status Register */ |
| 49 | #define FPEXC32_EL2 24 /* Floating-Point Exception Control Register */ | 62 | #define FPEXC32_EL2 90 /* Floating-Point Exception Control Register */ |
| 50 | #define DBGVCR32_EL2 25 /* Debug Vector Catch Register */ | 63 | #define DBGVCR32_EL2 91 /* Debug Vector Catch Register */ |
| 51 | #define TEECR32_EL1 26 /* ThumbEE Configuration Register */ | 64 | #define TEECR32_EL1 92 /* ThumbEE Configuration Register */ |
| 52 | #define TEEHBR32_EL1 27 /* ThumbEE Handler Base Register */ | 65 | #define TEEHBR32_EL1 93 /* ThumbEE Handler Base Register */ |
| 53 | #define NR_SYS_REGS 28 | 66 | #define NR_SYS_REGS 94 |
| 54 | 67 | ||
| 55 | /* 32bit mapping */ | 68 | /* 32bit mapping */ |
| 56 | #define c0_MPIDR (MPIDR_EL1 * 2) /* MultiProcessor ID Register */ | 69 | #define c0_MPIDR (MPIDR_EL1 * 2) /* MultiProcessor ID Register */ |
| @@ -82,11 +95,23 @@ | |||
| 82 | #define c10_AMAIR0 (AMAIR_EL1 * 2) /* Aux Memory Attr Indirection Reg */ | 95 | #define c10_AMAIR0 (AMAIR_EL1 * 2) /* Aux Memory Attr Indirection Reg */ |
| 83 | #define c10_AMAIR1 (c10_AMAIR0 + 1)/* Aux Memory Attr Indirection Reg */ | 96 | #define c10_AMAIR1 (c10_AMAIR0 + 1)/* Aux Memory Attr Indirection Reg */ |
| 84 | #define c14_CNTKCTL (CNTKCTL_EL1 * 2) /* Timer Control Register (PL1) */ | 97 | #define c14_CNTKCTL (CNTKCTL_EL1 * 2) /* Timer Control Register (PL1) */ |
| 85 | #define NR_CP15_REGS (NR_SYS_REGS * 2) | 98 | |
| 99 | #define cp14_DBGDSCRext (MDSCR_EL1 * 2) | ||
| 100 | #define cp14_DBGBCR0 (DBGBCR0_EL1 * 2) | ||
| 101 | #define cp14_DBGBVR0 (DBGBVR0_EL1 * 2) | ||
| 102 | #define cp14_DBGBXVR0 (cp14_DBGBVR0 + 1) | ||
| 103 | #define cp14_DBGWCR0 (DBGWCR0_EL1 * 2) | ||
| 104 | #define cp14_DBGWVR0 (DBGWVR0_EL1 * 2) | ||
| 105 | #define cp14_DBGDCCINT (MDCCINT_EL1 * 2) | ||
| 106 | |||
| 107 | #define NR_COPRO_REGS (NR_SYS_REGS * 2) | ||
| 86 | 108 | ||
| 87 | #define ARM_EXCEPTION_IRQ 0 | 109 | #define ARM_EXCEPTION_IRQ 0 |
| 88 | #define ARM_EXCEPTION_TRAP 1 | 110 | #define ARM_EXCEPTION_TRAP 1 |
| 89 | 111 | ||
| 112 | #define KVM_ARM64_DEBUG_DIRTY_SHIFT 0 | ||
| 113 | #define KVM_ARM64_DEBUG_DIRTY (1 << KVM_ARM64_DEBUG_DIRTY_SHIFT) | ||
| 114 | |||
| 90 | #ifndef __ASSEMBLY__ | 115 | #ifndef __ASSEMBLY__ |
| 91 | struct kvm; | 116 | struct kvm; |
| 92 | struct kvm_vcpu; | 117 | struct kvm_vcpu; |
| @@ -96,13 +121,21 @@ extern char __kvm_hyp_init_end[]; | |||
| 96 | 121 | ||
| 97 | extern char __kvm_hyp_vector[]; | 122 | extern char __kvm_hyp_vector[]; |
| 98 | 123 | ||
| 99 | extern char __kvm_hyp_code_start[]; | 124 | #define __kvm_hyp_code_start __hyp_text_start |
| 100 | extern char __kvm_hyp_code_end[]; | 125 | #define __kvm_hyp_code_end __hyp_text_end |
| 101 | 126 | ||
| 102 | extern void __kvm_flush_vm_context(void); | 127 | extern void __kvm_flush_vm_context(void); |
| 103 | extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa); | 128 | extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa); |
| 104 | 129 | ||
| 105 | extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu); | 130 | extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu); |
| 131 | |||
| 132 | extern u64 __vgic_v3_get_ich_vtr_el2(void); | ||
| 133 | |||
| 134 | extern char __save_vgic_v2_state[]; | ||
| 135 | extern char __restore_vgic_v2_state[]; | ||
| 136 | extern char __save_vgic_v3_state[]; | ||
| 137 | extern char __restore_vgic_v3_state[]; | ||
| 138 | |||
| 106 | #endif | 139 | #endif |
| 107 | 140 | ||
| 108 | #endif /* __ARM_KVM_ASM_H__ */ | 141 | #endif /* __ARM_KVM_ASM_H__ */ |
diff --git a/arch/arm64/include/asm/kvm_coproc.h b/arch/arm64/include/asm/kvm_coproc.h index 9a59301cd014..0b52377a6c11 100644 --- a/arch/arm64/include/asm/kvm_coproc.h +++ b/arch/arm64/include/asm/kvm_coproc.h | |||
| @@ -39,7 +39,8 @@ void kvm_register_target_sys_reg_table(unsigned int target, | |||
| 39 | struct kvm_sys_reg_target_table *table); | 39 | struct kvm_sys_reg_target_table *table); |
| 40 | 40 | ||
| 41 | int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run); | 41 | int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run); |
| 42 | int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run); | 42 | int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run); |
| 43 | int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run); | ||
| 43 | int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run); | 44 | int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run); |
| 44 | int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run); | 45 | int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run); |
| 45 | int kvm_handle_sys_reg(struct kvm_vcpu *vcpu, struct kvm_run *run); | 46 | int kvm_handle_sys_reg(struct kvm_vcpu *vcpu, struct kvm_run *run); |
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index dd8ecfc3f995..fdc3e21abd8d 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h | |||
| @@ -213,6 +213,17 @@ static inline unsigned long vcpu_data_guest_to_host(struct kvm_vcpu *vcpu, | |||
| 213 | default: | 213 | default: |
| 214 | return be64_to_cpu(data); | 214 | return be64_to_cpu(data); |
| 215 | } | 215 | } |
| 216 | } else { | ||
| 217 | switch (len) { | ||
| 218 | case 1: | ||
| 219 | return data & 0xff; | ||
| 220 | case 2: | ||
| 221 | return le16_to_cpu(data & 0xffff); | ||
| 222 | case 4: | ||
| 223 | return le32_to_cpu(data & 0xffffffff); | ||
| 224 | default: | ||
| 225 | return le64_to_cpu(data); | ||
| 226 | } | ||
| 216 | } | 227 | } |
| 217 | 228 | ||
| 218 | return data; /* Leave LE untouched */ | 229 | return data; /* Leave LE untouched */ |
| @@ -233,6 +244,17 @@ static inline unsigned long vcpu_data_host_to_guest(struct kvm_vcpu *vcpu, | |||
| 233 | default: | 244 | default: |
| 234 | return cpu_to_be64(data); | 245 | return cpu_to_be64(data); |
| 235 | } | 246 | } |
| 247 | } else { | ||
| 248 | switch (len) { | ||
| 249 | case 1: | ||
| 250 | return data & 0xff; | ||
| 251 | case 2: | ||
| 252 | return cpu_to_le16(data & 0xffff); | ||
| 253 | case 4: | ||
| 254 | return cpu_to_le32(data & 0xffffffff); | ||
| 255 | default: | ||
| 256 | return cpu_to_le64(data); | ||
| 257 | } | ||
| 236 | } | 258 | } |
| 237 | 259 | ||
| 238 | return data; /* Leave LE untouched */ | 260 | return data; /* Leave LE untouched */ |
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 92242ce06309..e10c45a578e3 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h | |||
| @@ -86,7 +86,7 @@ struct kvm_cpu_context { | |||
| 86 | struct kvm_regs gp_regs; | 86 | struct kvm_regs gp_regs; |
| 87 | union { | 87 | union { |
| 88 | u64 sys_regs[NR_SYS_REGS]; | 88 | u64 sys_regs[NR_SYS_REGS]; |
| 89 | u32 cp15[NR_CP15_REGS]; | 89 | u32 copro[NR_COPRO_REGS]; |
| 90 | }; | 90 | }; |
| 91 | }; | 91 | }; |
| 92 | 92 | ||
| @@ -101,6 +101,9 @@ struct kvm_vcpu_arch { | |||
| 101 | /* Exception Information */ | 101 | /* Exception Information */ |
| 102 | struct kvm_vcpu_fault_info fault; | 102 | struct kvm_vcpu_fault_info fault; |
| 103 | 103 | ||
| 104 | /* Debug state */ | ||
| 105 | u64 debug_flags; | ||
| 106 | |||
| 104 | /* Pointer to host CPU context */ | 107 | /* Pointer to host CPU context */ |
| 105 | kvm_cpu_context_t *host_cpu_context; | 108 | kvm_cpu_context_t *host_cpu_context; |
| 106 | 109 | ||
| @@ -138,7 +141,20 @@ struct kvm_vcpu_arch { | |||
| 138 | 141 | ||
| 139 | #define vcpu_gp_regs(v) (&(v)->arch.ctxt.gp_regs) | 142 | #define vcpu_gp_regs(v) (&(v)->arch.ctxt.gp_regs) |
| 140 | #define vcpu_sys_reg(v,r) ((v)->arch.ctxt.sys_regs[(r)]) | 143 | #define vcpu_sys_reg(v,r) ((v)->arch.ctxt.sys_regs[(r)]) |
| 141 | #define vcpu_cp15(v,r) ((v)->arch.ctxt.cp15[(r)]) | 144 | /* |
| 145 | * CP14 and CP15 live in the same array, as they are backed by the | ||
| 146 | * same system registers. | ||
| 147 | */ | ||
| 148 | #define vcpu_cp14(v,r) ((v)->arch.ctxt.copro[(r)]) | ||
| 149 | #define vcpu_cp15(v,r) ((v)->arch.ctxt.copro[(r)]) | ||
| 150 | |||
| 151 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
| 152 | #define vcpu_cp15_64_high(v,r) vcpu_cp15((v),(r)) | ||
| 153 | #define vcpu_cp15_64_low(v,r) vcpu_cp15((v),(r) + 1) | ||
| 154 | #else | ||
| 155 | #define vcpu_cp15_64_high(v,r) vcpu_cp15((v),(r) + 1) | ||
| 156 | #define vcpu_cp15_64_low(v,r) vcpu_cp15((v),(r)) | ||
| 157 | #endif | ||
| 142 | 158 | ||
| 143 | struct kvm_vm_stat { | 159 | struct kvm_vm_stat { |
| 144 | u32 remote_tlb_flush; | 160 | u32 remote_tlb_flush; |
| @@ -200,4 +216,32 @@ static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr, | |||
| 200 | hyp_stack_ptr, vector_ptr); | 216 | hyp_stack_ptr, vector_ptr); |
| 201 | } | 217 | } |
| 202 | 218 | ||
| 219 | struct vgic_sr_vectors { | ||
| 220 | void *save_vgic; | ||
| 221 | void *restore_vgic; | ||
| 222 | }; | ||
| 223 | |||
| 224 | static inline void vgic_arch_setup(const struct vgic_params *vgic) | ||
| 225 | { | ||
| 226 | extern struct vgic_sr_vectors __vgic_sr_vectors; | ||
| 227 | |||
| 228 | switch(vgic->type) | ||
| 229 | { | ||
| 230 | case VGIC_V2: | ||
| 231 | __vgic_sr_vectors.save_vgic = __save_vgic_v2_state; | ||
| 232 | __vgic_sr_vectors.restore_vgic = __restore_vgic_v2_state; | ||
| 233 | break; | ||
| 234 | |||
| 235 | #ifdef CONFIG_ARM_GIC_V3 | ||
| 236 | case VGIC_V3: | ||
| 237 | __vgic_sr_vectors.save_vgic = __save_vgic_v3_state; | ||
| 238 | __vgic_sr_vectors.restore_vgic = __restore_vgic_v3_state; | ||
| 239 | break; | ||
| 240 | #endif | ||
| 241 | |||
| 242 | default: | ||
| 243 | BUG(); | ||
| 244 | } | ||
| 245 | } | ||
| 246 | |||
| 203 | #endif /* __ARM64_KVM_HOST_H__ */ | 247 | #endif /* __ARM64_KVM_HOST_H__ */ |
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h index 7d29847a893b..8e138c7c53ac 100644 --- a/arch/arm64/include/asm/kvm_mmu.h +++ b/arch/arm64/include/asm/kvm_mmu.h | |||
| @@ -125,6 +125,21 @@ static inline void kvm_set_s2pmd_writable(pmd_t *pmd) | |||
| 125 | #define kvm_pud_addr_end(addr, end) pud_addr_end(addr, end) | 125 | #define kvm_pud_addr_end(addr, end) pud_addr_end(addr, end) |
| 126 | #define kvm_pmd_addr_end(addr, end) pmd_addr_end(addr, end) | 126 | #define kvm_pmd_addr_end(addr, end) pmd_addr_end(addr, end) |
| 127 | 127 | ||
| 128 | static inline bool kvm_page_empty(void *ptr) | ||
| 129 | { | ||
| 130 | struct page *ptr_page = virt_to_page(ptr); | ||
| 131 | return page_count(ptr_page) == 1; | ||
| 132 | } | ||
| 133 | |||
| 134 | #define kvm_pte_table_empty(ptep) kvm_page_empty(ptep) | ||
| 135 | #ifndef CONFIG_ARM64_64K_PAGES | ||
| 136 | #define kvm_pmd_table_empty(pmdp) kvm_page_empty(pmdp) | ||
| 137 | #else | ||
| 138 | #define kvm_pmd_table_empty(pmdp) (0) | ||
| 139 | #endif | ||
| 140 | #define kvm_pud_table_empty(pudp) (0) | ||
| 141 | |||
| 142 | |||
| 128 | struct kvm; | 143 | struct kvm; |
| 129 | 144 | ||
| 130 | #define kvm_flush_dcache_to_poc(a,l) __flush_dcache_area((a), (l)) | 145 | #define kvm_flush_dcache_to_poc(a,l) __flush_dcache_area((a), (l)) |
diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h index 215ad4649dd7..7a5df5252dd7 100644 --- a/arch/arm64/include/asm/virt.h +++ b/arch/arm64/include/asm/virt.h | |||
| @@ -50,6 +50,10 @@ static inline bool is_hyp_mode_mismatched(void) | |||
| 50 | return __boot_cpu_mode[0] != __boot_cpu_mode[1]; | 50 | return __boot_cpu_mode[0] != __boot_cpu_mode[1]; |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | /* The section containing the hypervisor text */ | ||
| 54 | extern char __hyp_text_start[]; | ||
| 55 | extern char __hyp_text_end[]; | ||
| 56 | |||
| 53 | #endif /* __ASSEMBLY__ */ | 57 | #endif /* __ASSEMBLY__ */ |
| 54 | 58 | ||
| 55 | #endif /* ! __ASM__VIRT_H */ | 59 | #endif /* ! __ASM__VIRT_H */ |
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c index 646f888387cd..9a9fce090d58 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c | |||
| @@ -120,6 +120,7 @@ int main(void) | |||
| 120 | DEFINE(VCPU_ESR_EL2, offsetof(struct kvm_vcpu, arch.fault.esr_el2)); | 120 | DEFINE(VCPU_ESR_EL2, offsetof(struct kvm_vcpu, arch.fault.esr_el2)); |
| 121 | DEFINE(VCPU_FAR_EL2, offsetof(struct kvm_vcpu, arch.fault.far_el2)); | 121 | DEFINE(VCPU_FAR_EL2, offsetof(struct kvm_vcpu, arch.fault.far_el2)); |
| 122 | DEFINE(VCPU_HPFAR_EL2, offsetof(struct kvm_vcpu, arch.fault.hpfar_el2)); | 122 | DEFINE(VCPU_HPFAR_EL2, offsetof(struct kvm_vcpu, arch.fault.hpfar_el2)); |
| 123 | DEFINE(VCPU_DEBUG_FLAGS, offsetof(struct kvm_vcpu, arch.debug_flags)); | ||
| 123 | DEFINE(VCPU_HCR_EL2, offsetof(struct kvm_vcpu, arch.hcr_el2)); | 124 | DEFINE(VCPU_HCR_EL2, offsetof(struct kvm_vcpu, arch.hcr_el2)); |
| 124 | DEFINE(VCPU_IRQ_LINES, offsetof(struct kvm_vcpu, arch.irq_lines)); | 125 | DEFINE(VCPU_IRQ_LINES, offsetof(struct kvm_vcpu, arch.irq_lines)); |
| 125 | DEFINE(VCPU_HOST_CONTEXT, offsetof(struct kvm_vcpu, arch.host_cpu_context)); | 126 | DEFINE(VCPU_HOST_CONTEXT, offsetof(struct kvm_vcpu, arch.host_cpu_context)); |
| @@ -129,13 +130,24 @@ int main(void) | |||
| 129 | DEFINE(KVM_TIMER_ENABLED, offsetof(struct kvm, arch.timer.enabled)); | 130 | DEFINE(KVM_TIMER_ENABLED, offsetof(struct kvm, arch.timer.enabled)); |
| 130 | DEFINE(VCPU_KVM, offsetof(struct kvm_vcpu, kvm)); | 131 | DEFINE(VCPU_KVM, offsetof(struct kvm_vcpu, kvm)); |
| 131 | DEFINE(VCPU_VGIC_CPU, offsetof(struct kvm_vcpu, arch.vgic_cpu)); | 132 | DEFINE(VCPU_VGIC_CPU, offsetof(struct kvm_vcpu, arch.vgic_cpu)); |
| 132 | DEFINE(VGIC_CPU_HCR, offsetof(struct vgic_cpu, vgic_hcr)); | 133 | DEFINE(VGIC_SAVE_FN, offsetof(struct vgic_sr_vectors, save_vgic)); |
| 133 | DEFINE(VGIC_CPU_VMCR, offsetof(struct vgic_cpu, vgic_vmcr)); | 134 | DEFINE(VGIC_RESTORE_FN, offsetof(struct vgic_sr_vectors, restore_vgic)); |
| 134 | DEFINE(VGIC_CPU_MISR, offsetof(struct vgic_cpu, vgic_misr)); | 135 | DEFINE(VGIC_SR_VECTOR_SZ, sizeof(struct vgic_sr_vectors)); |
| 135 | DEFINE(VGIC_CPU_EISR, offsetof(struct vgic_cpu, vgic_eisr)); | 136 | DEFINE(VGIC_V2_CPU_HCR, offsetof(struct vgic_cpu, vgic_v2.vgic_hcr)); |
| 136 | DEFINE(VGIC_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_elrsr)); | 137 | DEFINE(VGIC_V2_CPU_VMCR, offsetof(struct vgic_cpu, vgic_v2.vgic_vmcr)); |
| 137 | DEFINE(VGIC_CPU_APR, offsetof(struct vgic_cpu, vgic_apr)); | 138 | DEFINE(VGIC_V2_CPU_MISR, offsetof(struct vgic_cpu, vgic_v2.vgic_misr)); |
| 138 | DEFINE(VGIC_CPU_LR, offsetof(struct vgic_cpu, vgic_lr)); | 139 | DEFINE(VGIC_V2_CPU_EISR, offsetof(struct vgic_cpu, vgic_v2.vgic_eisr)); |
| 140 | DEFINE(VGIC_V2_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_v2.vgic_elrsr)); | ||
| 141 | DEFINE(VGIC_V2_CPU_APR, offsetof(struct vgic_cpu, vgic_v2.vgic_apr)); | ||
| 142 | DEFINE(VGIC_V2_CPU_LR, offsetof(struct vgic_cpu, vgic_v2.vgic_lr)); | ||
| 143 | DEFINE(VGIC_V3_CPU_HCR, offsetof(struct vgic_cpu, vgic_v3.vgic_hcr)); | ||
| 144 | DEFINE(VGIC_V3_CPU_VMCR, offsetof(struct vgic_cpu, vgic_v3.vgic_vmcr)); | ||
| 145 | DEFINE(VGIC_V3_CPU_MISR, offsetof(struct vgic_cpu, vgic_v3.vgic_misr)); | ||
| 146 | DEFINE(VGIC_V3_CPU_EISR, offsetof(struct vgic_cpu, vgic_v3.vgic_eisr)); | ||
| 147 | DEFINE(VGIC_V3_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_v3.vgic_elrsr)); | ||
| 148 | DEFINE(VGIC_V3_CPU_AP0R, offsetof(struct vgic_cpu, vgic_v3.vgic_ap0r)); | ||
| 149 | DEFINE(VGIC_V3_CPU_AP1R, offsetof(struct vgic_cpu, vgic_v3.vgic_ap1r)); | ||
| 150 | DEFINE(VGIC_V3_CPU_LR, offsetof(struct vgic_cpu, vgic_v3.vgic_lr)); | ||
| 139 | DEFINE(VGIC_CPU_NR_LR, offsetof(struct vgic_cpu, nr_lr)); | 151 | DEFINE(VGIC_CPU_NR_LR, offsetof(struct vgic_cpu, nr_lr)); |
| 140 | DEFINE(KVM_VTTBR, offsetof(struct kvm, arch.vttbr)); | 152 | DEFINE(KVM_VTTBR, offsetof(struct kvm, arch.vttbr)); |
| 141 | DEFINE(KVM_VGIC_VCTRL, offsetof(struct kvm, arch.vgic.vctrl_base)); | 153 | DEFINE(KVM_VGIC_VCTRL, offsetof(struct kvm, arch.vgic.vctrl_base)); |
diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c index fe5b94078d82..b056369fd47d 100644 --- a/arch/arm64/kernel/debug-monitors.c +++ b/arch/arm64/kernel/debug-monitors.c | |||
| @@ -30,15 +30,6 @@ | |||
| 30 | #include <asm/cputype.h> | 30 | #include <asm/cputype.h> |
| 31 | #include <asm/system_misc.h> | 31 | #include <asm/system_misc.h> |
| 32 | 32 | ||
| 33 | /* Low-level stepping controls. */ | ||
| 34 | #define DBG_MDSCR_SS (1 << 0) | ||
| 35 | #define DBG_SPSR_SS (1 << 21) | ||
| 36 | |||
| 37 | /* MDSCR_EL1 enabling bits */ | ||
| 38 | #define DBG_MDSCR_KDE (1 << 13) | ||
| 39 | #define DBG_MDSCR_MDE (1 << 15) | ||
| 40 | #define DBG_MDSCR_MASK ~(DBG_MDSCR_KDE | DBG_MDSCR_MDE) | ||
| 41 | |||
| 42 | /* Determine debug architecture. */ | 33 | /* Determine debug architecture. */ |
| 43 | u8 debug_monitors_arch(void) | 34 | u8 debug_monitors_arch(void) |
| 44 | { | 35 | { |
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile index 72a9fd583ad3..32a096174b94 100644 --- a/arch/arm64/kvm/Makefile +++ b/arch/arm64/kvm/Makefile | |||
| @@ -20,4 +20,8 @@ kvm-$(CONFIG_KVM_ARM_HOST) += hyp.o hyp-init.o handle_exit.o | |||
| 20 | kvm-$(CONFIG_KVM_ARM_HOST) += guest.o reset.o sys_regs.o sys_regs_generic_v8.o | 20 | kvm-$(CONFIG_KVM_ARM_HOST) += guest.o reset.o sys_regs.o sys_regs_generic_v8.o |
| 21 | 21 | ||
| 22 | kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic.o | 22 | kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic.o |
| 23 | kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v2.o | ||
| 24 | kvm-$(CONFIG_KVM_ARM_VGIC) += vgic-v2-switch.o | ||
| 25 | kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v3.o | ||
| 26 | kvm-$(CONFIG_KVM_ARM_VGIC) += vgic-v3-switch.o | ||
| 23 | kvm-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o | 27 | kvm-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o |
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c index 60b5c31f3c10..8d1ec2887a26 100644 --- a/arch/arm64/kvm/guest.c +++ b/arch/arm64/kvm/guest.c | |||
| @@ -136,13 +136,67 @@ static unsigned long num_core_regs(void) | |||
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | /** | 138 | /** |
| 139 | * ARM64 versions of the TIMER registers, always available on arm64 | ||
| 140 | */ | ||
| 141 | |||
| 142 | #define NUM_TIMER_REGS 3 | ||
| 143 | |||
| 144 | static bool is_timer_reg(u64 index) | ||
| 145 | { | ||
| 146 | switch (index) { | ||
| 147 | case KVM_REG_ARM_TIMER_CTL: | ||
| 148 | case KVM_REG_ARM_TIMER_CNT: | ||
| 149 | case KVM_REG_ARM_TIMER_CVAL: | ||
| 150 | return true; | ||
| 151 | } | ||
| 152 | return false; | ||
| 153 | } | ||
| 154 | |||
| 155 | static int copy_timer_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) | ||
| 156 | { | ||
| 157 | if (put_user(KVM_REG_ARM_TIMER_CTL, uindices)) | ||
| 158 | return -EFAULT; | ||
| 159 | uindices++; | ||
| 160 | if (put_user(KVM_REG_ARM_TIMER_CNT, uindices)) | ||
| 161 | return -EFAULT; | ||
| 162 | uindices++; | ||
| 163 | if (put_user(KVM_REG_ARM_TIMER_CVAL, uindices)) | ||
| 164 | return -EFAULT; | ||
| 165 | |||
| 166 | return 0; | ||
| 167 | } | ||
| 168 | |||
| 169 | static int set_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | ||
| 170 | { | ||
| 171 | void __user *uaddr = (void __user *)(long)reg->addr; | ||
| 172 | u64 val; | ||
| 173 | int ret; | ||
| 174 | |||
| 175 | ret = copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id)); | ||
| 176 | if (ret != 0) | ||
| 177 | return ret; | ||
| 178 | |||
| 179 | return kvm_arm_timer_set_reg(vcpu, reg->id, val); | ||
| 180 | } | ||
| 181 | |||
| 182 | static int get_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | ||
| 183 | { | ||
| 184 | void __user *uaddr = (void __user *)(long)reg->addr; | ||
| 185 | u64 val; | ||
| 186 | |||
| 187 | val = kvm_arm_timer_get_reg(vcpu, reg->id); | ||
| 188 | return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)); | ||
| 189 | } | ||
| 190 | |||
| 191 | /** | ||
| 139 | * kvm_arm_num_regs - how many registers do we present via KVM_GET_ONE_REG | 192 | * kvm_arm_num_regs - how many registers do we present via KVM_GET_ONE_REG |
| 140 | * | 193 | * |
| 141 | * This is for all registers. | 194 | * This is for all registers. |
| 142 | */ | 195 | */ |
| 143 | unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu) | 196 | unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu) |
| 144 | { | 197 | { |
| 145 | return num_core_regs() + kvm_arm_num_sys_reg_descs(vcpu); | 198 | return num_core_regs() + kvm_arm_num_sys_reg_descs(vcpu) |
| 199 | + NUM_TIMER_REGS; | ||
| 146 | } | 200 | } |
| 147 | 201 | ||
| 148 | /** | 202 | /** |
| @@ -154,6 +208,7 @@ int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) | |||
| 154 | { | 208 | { |
| 155 | unsigned int i; | 209 | unsigned int i; |
| 156 | const u64 core_reg = KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE; | 210 | const u64 core_reg = KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE; |
| 211 | int ret; | ||
| 157 | 212 | ||
| 158 | for (i = 0; i < sizeof(struct kvm_regs) / sizeof(__u32); i++) { | 213 | for (i = 0; i < sizeof(struct kvm_regs) / sizeof(__u32); i++) { |
| 159 | if (put_user(core_reg | i, uindices)) | 214 | if (put_user(core_reg | i, uindices)) |
| @@ -161,6 +216,11 @@ int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) | |||
| 161 | uindices++; | 216 | uindices++; |
| 162 | } | 217 | } |
| 163 | 218 | ||
| 219 | ret = copy_timer_indices(vcpu, uindices); | ||
| 220 | if (ret) | ||
| 221 | return ret; | ||
| 222 | uindices += NUM_TIMER_REGS; | ||
| 223 | |||
| 164 | return kvm_arm_copy_sys_reg_indices(vcpu, uindices); | 224 | return kvm_arm_copy_sys_reg_indices(vcpu, uindices); |
| 165 | } | 225 | } |
| 166 | 226 | ||
| @@ -174,6 +234,9 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | |||
| 174 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) | 234 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) |
| 175 | return get_core_reg(vcpu, reg); | 235 | return get_core_reg(vcpu, reg); |
| 176 | 236 | ||
| 237 | if (is_timer_reg(reg->id)) | ||
| 238 | return get_timer_reg(vcpu, reg); | ||
| 239 | |||
| 177 | return kvm_arm_sys_reg_get_reg(vcpu, reg); | 240 | return kvm_arm_sys_reg_get_reg(vcpu, reg); |
| 178 | } | 241 | } |
| 179 | 242 | ||
| @@ -187,6 +250,9 @@ int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | |||
| 187 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) | 250 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) |
| 188 | return set_core_reg(vcpu, reg); | 251 | return set_core_reg(vcpu, reg); |
| 189 | 252 | ||
| 253 | if (is_timer_reg(reg->id)) | ||
| 254 | return set_timer_reg(vcpu, reg); | ||
| 255 | |||
| 190 | return kvm_arm_sys_reg_set_reg(vcpu, reg); | 256 | return kvm_arm_sys_reg_set_reg(vcpu, reg); |
| 191 | } | 257 | } |
| 192 | 258 | ||
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c index 182415e1a952..e28be510380c 100644 --- a/arch/arm64/kvm/handle_exit.c +++ b/arch/arm64/kvm/handle_exit.c | |||
| @@ -73,9 +73,9 @@ static exit_handle_fn arm_exit_handlers[] = { | |||
| 73 | [ESR_EL2_EC_WFI] = kvm_handle_wfx, | 73 | [ESR_EL2_EC_WFI] = kvm_handle_wfx, |
| 74 | [ESR_EL2_EC_CP15_32] = kvm_handle_cp15_32, | 74 | [ESR_EL2_EC_CP15_32] = kvm_handle_cp15_32, |
| 75 | [ESR_EL2_EC_CP15_64] = kvm_handle_cp15_64, | 75 | [ESR_EL2_EC_CP15_64] = kvm_handle_cp15_64, |
| 76 | [ESR_EL2_EC_CP14_MR] = kvm_handle_cp14_access, | 76 | [ESR_EL2_EC_CP14_MR] = kvm_handle_cp14_32, |
| 77 | [ESR_EL2_EC_CP14_LS] = kvm_handle_cp14_load_store, | 77 | [ESR_EL2_EC_CP14_LS] = kvm_handle_cp14_load_store, |
| 78 | [ESR_EL2_EC_CP14_64] = kvm_handle_cp14_access, | 78 | [ESR_EL2_EC_CP14_64] = kvm_handle_cp14_64, |
| 79 | [ESR_EL2_EC_HVC32] = handle_hvc, | 79 | [ESR_EL2_EC_HVC32] = handle_hvc, |
| 80 | [ESR_EL2_EC_SMC32] = handle_smc, | 80 | [ESR_EL2_EC_SMC32] = handle_smc, |
| 81 | [ESR_EL2_EC_HVC64] = handle_hvc, | 81 | [ESR_EL2_EC_HVC64] = handle_hvc, |
diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S index b0d1512acf08..b72aa9f9215c 100644 --- a/arch/arm64/kvm/hyp.S +++ b/arch/arm64/kvm/hyp.S | |||
| @@ -16,11 +16,11 @@ | |||
| 16 | */ | 16 | */ |
| 17 | 17 | ||
| 18 | #include <linux/linkage.h> | 18 | #include <linux/linkage.h> |
| 19 | #include <linux/irqchip/arm-gic.h> | ||
| 20 | 19 | ||
| 21 | #include <asm/assembler.h> | 20 | #include <asm/assembler.h> |
| 22 | #include <asm/memory.h> | 21 | #include <asm/memory.h> |
| 23 | #include <asm/asm-offsets.h> | 22 | #include <asm/asm-offsets.h> |
| 23 | #include <asm/debug-monitors.h> | ||
| 24 | #include <asm/fpsimdmacros.h> | 24 | #include <asm/fpsimdmacros.h> |
| 25 | #include <asm/kvm.h> | 25 | #include <asm/kvm.h> |
| 26 | #include <asm/kvm_asm.h> | 26 | #include <asm/kvm_asm.h> |
| @@ -36,9 +36,6 @@ | |||
| 36 | .pushsection .hyp.text, "ax" | 36 | .pushsection .hyp.text, "ax" |
| 37 | .align PAGE_SHIFT | 37 | .align PAGE_SHIFT |
| 38 | 38 | ||
| 39 | __kvm_hyp_code_start: | ||
| 40 | .globl __kvm_hyp_code_start | ||
| 41 | |||
| 42 | .macro save_common_regs | 39 | .macro save_common_regs |
| 43 | // x2: base address for cpu context | 40 | // x2: base address for cpu context |
| 44 | // x3: tmp register | 41 | // x3: tmp register |
| @@ -215,6 +212,7 @@ __kvm_hyp_code_start: | |||
| 215 | mrs x22, amair_el1 | 212 | mrs x22, amair_el1 |
| 216 | mrs x23, cntkctl_el1 | 213 | mrs x23, cntkctl_el1 |
| 217 | mrs x24, par_el1 | 214 | mrs x24, par_el1 |
| 215 | mrs x25, mdscr_el1 | ||
| 218 | 216 | ||
| 219 | stp x4, x5, [x3] | 217 | stp x4, x5, [x3] |
| 220 | stp x6, x7, [x3, #16] | 218 | stp x6, x7, [x3, #16] |
| @@ -226,7 +224,202 @@ __kvm_hyp_code_start: | |||
| 226 | stp x18, x19, [x3, #112] | 224 | stp x18, x19, [x3, #112] |
| 227 | stp x20, x21, [x3, #128] | 225 | stp x20, x21, [x3, #128] |
| 228 | stp x22, x23, [x3, #144] | 226 | stp x22, x23, [x3, #144] |
| 229 | str x24, [x3, #160] | 227 | stp x24, x25, [x3, #160] |
| 228 | .endm | ||
| 229 | |||
| 230 | .macro save_debug | ||
| 231 | // x2: base address for cpu context | ||
| 232 | // x3: tmp register | ||
| 233 | |||
| 234 | mrs x26, id_aa64dfr0_el1 | ||
| 235 | ubfx x24, x26, #12, #4 // Extract BRPs | ||
| 236 | ubfx x25, x26, #20, #4 // Extract WRPs | ||
| 237 | mov w26, #15 | ||
| 238 | sub w24, w26, w24 // How many BPs to skip | ||
| 239 | sub w25, w26, w25 // How many WPs to skip | ||
| 240 | |||
| 241 | add x3, x2, #CPU_SYSREG_OFFSET(DBGBCR0_EL1) | ||
| 242 | |||
| 243 | adr x26, 1f | ||
| 244 | add x26, x26, x24, lsl #2 | ||
| 245 | br x26 | ||
| 246 | 1: | ||
| 247 | mrs x20, dbgbcr15_el1 | ||
| 248 | mrs x19, dbgbcr14_el1 | ||
| 249 | mrs x18, dbgbcr13_el1 | ||
| 250 | mrs x17, dbgbcr12_el1 | ||
| 251 | mrs x16, dbgbcr11_el1 | ||
| 252 | mrs x15, dbgbcr10_el1 | ||
| 253 | mrs x14, dbgbcr9_el1 | ||
| 254 | mrs x13, dbgbcr8_el1 | ||
| 255 | mrs x12, dbgbcr7_el1 | ||
| 256 | mrs x11, dbgbcr6_el1 | ||
| 257 | mrs x10, dbgbcr5_el1 | ||
| 258 | mrs x9, dbgbcr4_el1 | ||
| 259 | mrs x8, dbgbcr3_el1 | ||
| 260 | mrs x7, dbgbcr2_el1 | ||
| 261 | mrs x6, dbgbcr1_el1 | ||
| 262 | mrs x5, dbgbcr0_el1 | ||
| 263 | |||
| 264 | adr x26, 1f | ||
| 265 | add x26, x26, x24, lsl #2 | ||
| 266 | br x26 | ||
| 267 | |||
| 268 | 1: | ||
| 269 | str x20, [x3, #(15 * 8)] | ||
| 270 | str x19, [x3, #(14 * 8)] | ||
| 271 | str x18, [x3, #(13 * 8)] | ||
| 272 | str x17, [x3, #(12 * 8)] | ||
| 273 | str x16, [x3, #(11 * 8)] | ||
| 274 | str x15, [x3, #(10 * 8)] | ||
| 275 | str x14, [x3, #(9 * 8)] | ||
| 276 | str x13, [x3, #(8 * 8)] | ||
| 277 | str x12, [x3, #(7 * 8)] | ||
| 278 | str x11, [x3, #(6 * 8)] | ||
| 279 | str x10, [x3, #(5 * 8)] | ||
| 280 | str x9, [x3, #(4 * 8)] | ||
| 281 | str x8, [x3, #(3 * 8)] | ||
| 282 | str x7, [x3, #(2 * 8)] | ||
| 283 | str x6, [x3, #(1 * 8)] | ||
| 284 | str x5, [x3, #(0 * 8)] | ||
| 285 | |||
| 286 | add x3, x2, #CPU_SYSREG_OFFSET(DBGBVR0_EL1) | ||
| 287 | |||
| 288 | adr x26, 1f | ||
| 289 | add x26, x26, x24, lsl #2 | ||
| 290 | br x26 | ||
| 291 | 1: | ||
| 292 | mrs x20, dbgbvr15_el1 | ||
| 293 | mrs x19, dbgbvr14_el1 | ||
| 294 | mrs x18, dbgbvr13_el1 | ||
| 295 | mrs x17, dbgbvr12_el1 | ||
| 296 | mrs x16, dbgbvr11_el1 | ||
| 297 | mrs x15, dbgbvr10_el1 | ||
| 298 | mrs x14, dbgbvr9_el1 | ||
| 299 | mrs x13, dbgbvr8_el1 | ||
| 300 | mrs x12, dbgbvr7_el1 | ||
| 301 | mrs x11, dbgbvr6_el1 | ||
| 302 | mrs x10, dbgbvr5_el1 | ||
| 303 | mrs x9, dbgbvr4_el1 | ||
| 304 | mrs x8, dbgbvr3_el1 | ||
| 305 | mrs x7, dbgbvr2_el1 | ||
| 306 | mrs x6, dbgbvr1_el1 | ||
| 307 | mrs x5, dbgbvr0_el1 | ||
| 308 | |||
| 309 | adr x26, 1f | ||
| 310 | add x26, x26, x24, lsl #2 | ||
| 311 | br x26 | ||
| 312 | |||
| 313 | 1: | ||
| 314 | str x20, [x3, #(15 * 8)] | ||
| 315 | str x19, [x3, #(14 * 8)] | ||
| 316 | str x18, [x3, #(13 * 8)] | ||
| 317 | str x17, [x3, #(12 * 8)] | ||
| 318 | str x16, [x3, #(11 * 8)] | ||
| 319 | str x15, [x3, #(10 * 8)] | ||
| 320 | str x14, [x3, #(9 * 8)] | ||
| 321 | str x13, [x3, #(8 * 8)] | ||
| 322 | str x12, [x3, #(7 * 8)] | ||
| 323 | str x11, [x3, #(6 * 8)] | ||
| 324 | str x10, [x3, #(5 * 8)] | ||
| 325 | str x9, [x3, #(4 * 8)] | ||
| 326 | str x8, [x3, #(3 * 8)] | ||
| 327 | str x7, [x3, #(2 * 8)] | ||
| 328 | str x6, [x3, #(1 * 8)] | ||
| 329 | str x5, [x3, #(0 * 8)] | ||
| 330 | |||
| 331 | add x3, x2, #CPU_SYSREG_OFFSET(DBGWCR0_EL1) | ||
| 332 | |||
| 333 | adr x26, 1f | ||
| 334 | add x26, x26, x25, lsl #2 | ||
| 335 | br x26 | ||
| 336 | 1: | ||
| 337 | mrs x20, dbgwcr15_el1 | ||
| 338 | mrs x19, dbgwcr14_el1 | ||
| 339 | mrs x18, dbgwcr13_el1 | ||
| 340 | mrs x17, dbgwcr12_el1 | ||
| 341 | mrs x16, dbgwcr11_el1 | ||
| 342 | mrs x15, dbgwcr10_el1 | ||
| 343 | mrs x14, dbgwcr9_el1 | ||
| 344 | mrs x13, dbgwcr8_el1 | ||
| 345 | mrs x12, dbgwcr7_el1 | ||
| 346 | mrs x11, dbgwcr6_el1 | ||
| 347 | mrs x10, dbgwcr5_el1 | ||
| 348 | mrs x9, dbgwcr4_el1 | ||
| 349 | mrs x8, dbgwcr3_el1 | ||
| 350 | mrs x7, dbgwcr2_el1 | ||
| 351 | mrs x6, dbgwcr1_el1 | ||
| 352 | mrs x5, dbgwcr0_el1 | ||
| 353 | |||
| 354 | adr x26, 1f | ||
| 355 | add x26, x26, x25, lsl #2 | ||
| 356 | br x26 | ||
| 357 | |||
| 358 | 1: | ||
| 359 | str x20, [x3, #(15 * 8)] | ||
| 360 | str x19, [x3, #(14 * 8)] | ||
| 361 | str x18, [x3, #(13 * 8)] | ||
| 362 | str x17, [x3, #(12 * 8)] | ||
| 363 | str x16, [x3, #(11 * 8)] | ||
| 364 | str x15, [x3, #(10 * 8)] | ||
| 365 | str x14, [x3, #(9 * 8)] | ||
| 366 | str x13, [x3, #(8 * 8)] | ||
| 367 | str x12, [x3, #(7 * 8)] | ||
| 368 | str x11, [x3, #(6 * 8)] | ||
| 369 | str x10, [x3, #(5 * 8)] | ||
| 370 | str x9, [x3, #(4 * 8)] | ||
| 371 | str x8, [x3, #(3 * 8)] | ||
| 372 | str x7, [x3, #(2 * 8)] | ||
| 373 | str x6, [x3, #(1 * 8)] | ||
| 374 | str x5, [x3, #(0 * 8)] | ||
| 375 | |||
| 376 | add x3, x2, #CPU_SYSREG_OFFSET(DBGWVR0_EL1) | ||
| 377 | |||
| 378 | adr x26, 1f | ||
| 379 | add x26, x26, x25, lsl #2 | ||
| 380 | br x26 | ||
| 381 | 1: | ||
| 382 | mrs x20, dbgwvr15_el1 | ||
| 383 | mrs x19, dbgwvr14_el1 | ||
| 384 | mrs x18, dbgwvr13_el1 | ||
| 385 | mrs x17, dbgwvr12_el1 | ||
| 386 | mrs x16, dbgwvr11_el1 | ||
| 387 | mrs x15, dbgwvr10_el1 | ||
| 388 | mrs x14, dbgwvr9_el1 | ||
| 389 | mrs x13, dbgwvr8_el1 | ||
| 390 | mrs x12, dbgwvr7_el1 | ||
| 391 | mrs x11, dbgwvr6_el1 | ||
| 392 | mrs x10, dbgwvr5_el1 | ||
| 393 | mrs x9, dbgwvr4_el1 | ||
| 394 | mrs x8, dbgwvr3_el1 | ||
| 395 | mrs x7, dbgwvr2_el1 | ||
| 396 | mrs x6, dbgwvr1_el1 | ||
| 397 | mrs x5, dbgwvr0_el1 | ||
| 398 | |||
| 399 | adr x26, 1f | ||
| 400 | add x26, x26, x25, lsl #2 | ||
| 401 | br x26 | ||
| 402 | |||
| 403 | 1: | ||
| 404 | str x20, [x3, #(15 * 8)] | ||
| 405 | str x19, [x3, #(14 * 8)] | ||
| 406 | str x18, [x3, #(13 * 8)] | ||
| 407 | str x17, [x3, #(12 * 8)] | ||
| 408 | str x16, [x3, #(11 * 8)] | ||
| 409 | str x15, [x3, #(10 * 8)] | ||
| 410 | str x14, [x3, #(9 * 8)] | ||
| 411 | str x13, [x3, #(8 * 8)] | ||
| 412 | str x12, [x3, #(7 * 8)] | ||
| 413 | str x11, [x3, #(6 * 8)] | ||
| 414 | str x10, [x3, #(5 * 8)] | ||
| 415 | str x9, [x3, #(4 * 8)] | ||
| 416 | str x8, [x3, #(3 * 8)] | ||
| 417 | str x7, [x3, #(2 * 8)] | ||
| 418 | str x6, [x3, #(1 * 8)] | ||
| 419 | str x5, [x3, #(0 * 8)] | ||
| 420 | |||
| 421 | mrs x21, mdccint_el1 | ||
| 422 | str x21, [x2, #CPU_SYSREG_OFFSET(MDCCINT_EL1)] | ||
| 230 | .endm | 423 | .endm |
| 231 | 424 | ||
| 232 | .macro restore_sysregs | 425 | .macro restore_sysregs |
| @@ -245,7 +438,7 @@ __kvm_hyp_code_start: | |||
| 245 | ldp x18, x19, [x3, #112] | 438 | ldp x18, x19, [x3, #112] |
| 246 | ldp x20, x21, [x3, #128] | 439 | ldp x20, x21, [x3, #128] |
| 247 | ldp x22, x23, [x3, #144] | 440 | ldp x22, x23, [x3, #144] |
| 248 | ldr x24, [x3, #160] | 441 | ldp x24, x25, [x3, #160] |
| 249 | 442 | ||
| 250 | msr vmpidr_el2, x4 | 443 | msr vmpidr_el2, x4 |
| 251 | msr csselr_el1, x5 | 444 | msr csselr_el1, x5 |
| @@ -268,6 +461,198 @@ __kvm_hyp_code_start: | |||
| 268 | msr amair_el1, x22 | 461 | msr amair_el1, x22 |
| 269 | msr cntkctl_el1, x23 | 462 | msr cntkctl_el1, x23 |
| 270 | msr par_el1, x24 | 463 | msr par_el1, x24 |
| 464 | msr mdscr_el1, x25 | ||
| 465 | .endm | ||
| 466 | |||
| 467 | .macro restore_debug | ||
| 468 | // x2: base address for cpu context | ||
| 469 | // x3: tmp register | ||
| 470 | |||
| 471 | mrs x26, id_aa64dfr0_el1 | ||
| 472 | ubfx x24, x26, #12, #4 // Extract BRPs | ||
| 473 | ubfx x25, x26, #20, #4 // Extract WRPs | ||
| 474 | mov w26, #15 | ||
| 475 | sub w24, w26, w24 // How many BPs to skip | ||
| 476 | sub w25, w26, w25 // How many WPs to skip | ||
| 477 | |||
| 478 | add x3, x2, #CPU_SYSREG_OFFSET(DBGBCR0_EL1) | ||
| 479 | |||
| 480 | adr x26, 1f | ||
| 481 | add x26, x26, x24, lsl #2 | ||
| 482 | br x26 | ||
| 483 | 1: | ||
| 484 | ldr x20, [x3, #(15 * 8)] | ||
| 485 | ldr x19, [x3, #(14 * 8)] | ||
| 486 | ldr x18, [x3, #(13 * 8)] | ||
| 487 | ldr x17, [x3, #(12 * 8)] | ||
| 488 | ldr x16, [x3, #(11 * 8)] | ||
| 489 | ldr x15, [x3, #(10 * 8)] | ||
| 490 | ldr x14, [x3, #(9 * 8)] | ||
| 491 | ldr x13, [x3, #(8 * 8)] | ||
| 492 | ldr x12, [x3, #(7 * 8)] | ||
| 493 | ldr x11, [x3, #(6 * 8)] | ||
| 494 | ldr x10, [x3, #(5 * 8)] | ||
| 495 | ldr x9, [x3, #(4 * 8)] | ||
| 496 | ldr x8, [x3, #(3 * 8)] | ||
| 497 | ldr x7, [x3, #(2 * 8)] | ||
| 498 | ldr x6, [x3, #(1 * 8)] | ||
| 499 | ldr x5, [x3, #(0 * 8)] | ||
| 500 | |||
| 501 | adr x26, 1f | ||
| 502 | add x26, x26, x24, lsl #2 | ||
| 503 | br x26 | ||
| 504 | 1: | ||
| 505 | msr dbgbcr15_el1, x20 | ||
| 506 | msr dbgbcr14_el1, x19 | ||
| 507 | msr dbgbcr13_el1, x18 | ||
| 508 | msr dbgbcr12_el1, x17 | ||
| 509 | msr dbgbcr11_el1, x16 | ||
| 510 | msr dbgbcr10_el1, x15 | ||
| 511 | msr dbgbcr9_el1, x14 | ||
| 512 | msr dbgbcr8_el1, x13 | ||
| 513 | msr dbgbcr7_el1, x12 | ||
| 514 | msr dbgbcr6_el1, x11 | ||
| 515 | msr dbgbcr5_el1, x10 | ||
| 516 | msr dbgbcr4_el1, x9 | ||
| 517 | msr dbgbcr3_el1, x8 | ||
| 518 | msr dbgbcr2_el1, x7 | ||
| 519 | msr dbgbcr1_el1, x6 | ||
| 520 | msr dbgbcr0_el1, x5 | ||
| 521 | |||
| 522 | add x3, x2, #CPU_SYSREG_OFFSET(DBGBVR0_EL1) | ||
| 523 | |||
| 524 | adr x26, 1f | ||
| 525 | add x26, x26, x24, lsl #2 | ||
| 526 | br x26 | ||
| 527 | 1: | ||
| 528 | ldr x20, [x3, #(15 * 8)] | ||
| 529 | ldr x19, [x3, #(14 * 8)] | ||
| 530 | ldr x18, [x3, #(13 * 8)] | ||
| 531 | ldr x17, [x3, #(12 * 8)] | ||
| 532 | ldr x16, [x3, #(11 * 8)] | ||
| 533 | ldr x15, [x3, #(10 * 8)] | ||
| 534 | ldr x14, [x3, #(9 * 8)] | ||
| 535 | ldr x13, [x3, #(8 * 8)] | ||
| 536 | ldr x12, [x3, #(7 * 8)] | ||
| 537 | ldr x11, [x3, #(6 * 8)] | ||
| 538 | ldr x10, [x3, #(5 * 8)] | ||
| 539 | ldr x9, [x3, #(4 * 8)] | ||
| 540 | ldr x8, [x3, #(3 * 8)] | ||
| 541 | ldr x7, [x3, #(2 * 8)] | ||
| 542 | ldr x6, [x3, #(1 * 8)] | ||
| 543 | ldr x5, [x3, #(0 * 8)] | ||
| 544 | |||
| 545 | adr x26, 1f | ||
| 546 | add x26, x26, x24, lsl #2 | ||
| 547 | br x26 | ||
| 548 | 1: | ||
| 549 | msr dbgbvr15_el1, x20 | ||
| 550 | msr dbgbvr14_el1, x19 | ||
| 551 | msr dbgbvr13_el1, x18 | ||
| 552 | msr dbgbvr12_el1, x17 | ||
| 553 | msr dbgbvr11_el1, x16 | ||
| 554 | msr dbgbvr10_el1, x15 | ||
| 555 | msr dbgbvr9_el1, x14 | ||
| 556 | msr dbgbvr8_el1, x13 | ||
| 557 | msr dbgbvr7_el1, x12 | ||
| 558 | msr dbgbvr6_el1, x11 | ||
| 559 | msr dbgbvr5_el1, x10 | ||
| 560 | msr dbgbvr4_el1, x9 | ||
| 561 | msr dbgbvr3_el1, x8 | ||
| 562 | msr dbgbvr2_el1, x7 | ||
| 563 | msr dbgbvr1_el1, x6 | ||
| 564 | msr dbgbvr0_el1, x5 | ||
| 565 | |||
| 566 | add x3, x2, #CPU_SYSREG_OFFSET(DBGWCR0_EL1) | ||
| 567 | |||
| 568 | adr x26, 1f | ||
| 569 | add x26, x26, x25, lsl #2 | ||
| 570 | br x26 | ||
| 571 | 1: | ||
| 572 | ldr x20, [x3, #(15 * 8)] | ||
| 573 | ldr x19, [x3, #(14 * 8)] | ||
| 574 | ldr x18, [x3, #(13 * 8)] | ||
| 575 | ldr x17, [x3, #(12 * 8)] | ||
| 576 | ldr x16, [x3, #(11 * 8)] | ||
| 577 | ldr x15, [x3, #(10 * 8)] | ||
| 578 | ldr x14, [x3, #(9 * 8)] | ||
| 579 | ldr x13, [x3, #(8 * 8)] | ||
| 580 | ldr x12, [x3, #(7 * 8)] | ||
| 581 | ldr x11, [x3, #(6 * 8)] | ||
| 582 | ldr x10, [x3, #(5 * 8)] | ||
| 583 | ldr x9, [x3, #(4 * 8)] | ||
| 584 | ldr x8, [x3, #(3 * 8)] | ||
| 585 | ldr x7, [x3, #(2 * 8)] | ||
| 586 | ldr x6, [x3, #(1 * 8)] | ||
| 587 | ldr x5, [x3, #(0 * 8)] | ||
| 588 | |||
| 589 | adr x26, 1f | ||
| 590 | add x26, x26, x25, lsl #2 | ||
| 591 | br x26 | ||
| 592 | 1: | ||
| 593 | msr dbgwcr15_el1, x20 | ||
| 594 | msr dbgwcr14_el1, x19 | ||
| 595 | msr dbgwcr13_el1, x18 | ||
| 596 | msr dbgwcr12_el1, x17 | ||
| 597 | msr dbgwcr11_el1, x16 | ||
| 598 | msr dbgwcr10_el1, x15 | ||
| 599 | msr dbgwcr9_el1, x14 | ||
| 600 | msr dbgwcr8_el1, x13 | ||
| 601 | msr dbgwcr7_el1, x12 | ||
| 602 | msr dbgwcr6_el1, x11 | ||
| 603 | msr dbgwcr5_el1, x10 | ||
| 604 | msr dbgwcr4_el1, x9 | ||
| 605 | msr dbgwcr3_el1, x8 | ||
| 606 | msr dbgwcr2_el1, x7 | ||
| 607 | msr dbgwcr1_el1, x6 | ||
| 608 | msr dbgwcr0_el1, x5 | ||
| 609 | |||
| 610 | add x3, x2, #CPU_SYSREG_OFFSET(DBGWVR0_EL1) | ||
| 611 | |||
| 612 | adr x26, 1f | ||
| 613 | add x26, x26, x25, lsl #2 | ||
| 614 | br x26 | ||
| 615 | 1: | ||
| 616 | ldr x20, [x3, #(15 * 8)] | ||
| 617 | ldr x19, [x3, #(14 * 8)] | ||
| 618 | ldr x18, [x3, #(13 * 8)] | ||
| 619 | ldr x17, [x3, #(12 * 8)] | ||
| 620 | ldr x16, [x3, #(11 * 8)] | ||
| 621 | ldr x15, [x3, #(10 * 8)] | ||
| 622 | ldr x14, [x3, #(9 * 8)] | ||
| 623 | ldr x13, [x3, #(8 * 8)] | ||
| 624 | ldr x12, [x3, #(7 * 8)] | ||
| 625 | ldr x11, [x3, #(6 * 8)] | ||
| 626 | ldr x10, [x3, #(5 * 8)] | ||
| 627 | ldr x9, [x3, #(4 * 8)] | ||
| 628 | ldr x8, [x3, #(3 * 8)] | ||
| 629 | ldr x7, [x3, #(2 * 8)] | ||
| 630 | ldr x6, [x3, #(1 * 8)] | ||
| 631 | ldr x5, [x3, #(0 * 8)] | ||
| 632 | |||
| 633 | adr x26, 1f | ||
| 634 | add x26, x26, x25, lsl #2 | ||
| 635 | br x26 | ||
| 636 | 1: | ||
| 637 | msr dbgwvr15_el1, x20 | ||
| 638 | msr dbgwvr14_el1, x19 | ||
| 639 | msr dbgwvr13_el1, x18 | ||
| 640 | msr dbgwvr12_el1, x17 | ||
| 641 | msr dbgwvr11_el1, x16 | ||
| 642 | msr dbgwvr10_el1, x15 | ||
| 643 | msr dbgwvr9_el1, x14 | ||
| 644 | msr dbgwvr8_el1, x13 | ||
| 645 | msr dbgwvr7_el1, x12 | ||
| 646 | msr dbgwvr6_el1, x11 | ||
| 647 | msr dbgwvr5_el1, x10 | ||
| 648 | msr dbgwvr4_el1, x9 | ||
| 649 | msr dbgwvr3_el1, x8 | ||
| 650 | msr dbgwvr2_el1, x7 | ||
| 651 | msr dbgwvr1_el1, x6 | ||
| 652 | msr dbgwvr0_el1, x5 | ||
| 653 | |||
| 654 | ldr x21, [x2, #CPU_SYSREG_OFFSET(MDCCINT_EL1)] | ||
| 655 | msr mdccint_el1, x21 | ||
| 271 | .endm | 656 | .endm |
| 272 | 657 | ||
| 273 | .macro skip_32bit_state tmp, target | 658 | .macro skip_32bit_state tmp, target |
| @@ -282,6 +667,35 @@ __kvm_hyp_code_start: | |||
| 282 | tbz \tmp, #12, \target | 667 | tbz \tmp, #12, \target |
| 283 | .endm | 668 | .endm |
| 284 | 669 | ||
| 670 | .macro skip_debug_state tmp, target | ||
| 671 | ldr \tmp, [x0, #VCPU_DEBUG_FLAGS] | ||
| 672 | tbz \tmp, #KVM_ARM64_DEBUG_DIRTY_SHIFT, \target | ||
| 673 | .endm | ||
| 674 | |||
| 675 | .macro compute_debug_state target | ||
| 676 | // Compute debug state: If any of KDE, MDE or KVM_ARM64_DEBUG_DIRTY | ||
| 677 | // is set, we do a full save/restore cycle and disable trapping. | ||
| 678 | add x25, x0, #VCPU_CONTEXT | ||
| 679 | |||
| 680 | // Check the state of MDSCR_EL1 | ||
| 681 | ldr x25, [x25, #CPU_SYSREG_OFFSET(MDSCR_EL1)] | ||
| 682 | and x26, x25, #DBG_MDSCR_KDE | ||
| 683 | and x25, x25, #DBG_MDSCR_MDE | ||
| 684 | adds xzr, x25, x26 | ||
| 685 | b.eq 9998f // Nothing to see there | ||
| 686 | |||
| 687 | // If any interesting bits was set, we must set the flag | ||
| 688 | mov x26, #KVM_ARM64_DEBUG_DIRTY | ||
| 689 | str x26, [x0, #VCPU_DEBUG_FLAGS] | ||
| 690 | b 9999f // Don't skip restore | ||
| 691 | |||
| 692 | 9998: | ||
| 693 | // Otherwise load the flags from memory in case we recently | ||
| 694 | // trapped | ||
| 695 | skip_debug_state x25, \target | ||
| 696 | 9999: | ||
| 697 | .endm | ||
| 698 | |||
| 285 | .macro save_guest_32bit_state | 699 | .macro save_guest_32bit_state |
| 286 | skip_32bit_state x3, 1f | 700 | skip_32bit_state x3, 1f |
| 287 | 701 | ||
| @@ -297,10 +711,13 @@ __kvm_hyp_code_start: | |||
| 297 | mrs x4, dacr32_el2 | 711 | mrs x4, dacr32_el2 |
| 298 | mrs x5, ifsr32_el2 | 712 | mrs x5, ifsr32_el2 |
| 299 | mrs x6, fpexc32_el2 | 713 | mrs x6, fpexc32_el2 |
| 300 | mrs x7, dbgvcr32_el2 | ||
| 301 | stp x4, x5, [x3] | 714 | stp x4, x5, [x3] |
| 302 | stp x6, x7, [x3, #16] | 715 | str x6, [x3, #16] |
| 303 | 716 | ||
| 717 | skip_debug_state x8, 2f | ||
| 718 | mrs x7, dbgvcr32_el2 | ||
| 719 | str x7, [x3, #24] | ||
| 720 | 2: | ||
| 304 | skip_tee_state x8, 1f | 721 | skip_tee_state x8, 1f |
| 305 | 722 | ||
| 306 | add x3, x2, #CPU_SYSREG_OFFSET(TEECR32_EL1) | 723 | add x3, x2, #CPU_SYSREG_OFFSET(TEECR32_EL1) |
| @@ -323,12 +740,15 @@ __kvm_hyp_code_start: | |||
| 323 | 740 | ||
| 324 | add x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2) | 741 | add x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2) |
| 325 | ldp x4, x5, [x3] | 742 | ldp x4, x5, [x3] |
| 326 | ldp x6, x7, [x3, #16] | 743 | ldr x6, [x3, #16] |
| 327 | msr dacr32_el2, x4 | 744 | msr dacr32_el2, x4 |
| 328 | msr ifsr32_el2, x5 | 745 | msr ifsr32_el2, x5 |
| 329 | msr fpexc32_el2, x6 | 746 | msr fpexc32_el2, x6 |
| 330 | msr dbgvcr32_el2, x7 | ||
| 331 | 747 | ||
| 748 | skip_debug_state x8, 2f | ||
| 749 | ldr x7, [x3, #24] | ||
| 750 | msr dbgvcr32_el2, x7 | ||
| 751 | 2: | ||
| 332 | skip_tee_state x8, 1f | 752 | skip_tee_state x8, 1f |
| 333 | 753 | ||
| 334 | add x3, x2, #CPU_SYSREG_OFFSET(TEECR32_EL1) | 754 | add x3, x2, #CPU_SYSREG_OFFSET(TEECR32_EL1) |
| @@ -339,11 +759,8 @@ __kvm_hyp_code_start: | |||
| 339 | .endm | 759 | .endm |
| 340 | 760 | ||
| 341 | .macro activate_traps | 761 | .macro activate_traps |
| 342 | ldr x2, [x0, #VCPU_IRQ_LINES] | 762 | ldr x2, [x0, #VCPU_HCR_EL2] |
| 343 | ldr x1, [x0, #VCPU_HCR_EL2] | 763 | msr hcr_el2, x2 |
| 344 | orr x2, x2, x1 | ||
| 345 | msr hcr_el2, x2 | ||
| 346 | |||
| 347 | ldr x2, =(CPTR_EL2_TTA) | 764 | ldr x2, =(CPTR_EL2_TTA) |
| 348 | msr cptr_el2, x2 | 765 | msr cptr_el2, x2 |
| 349 | 766 | ||
| @@ -353,6 +770,14 @@ __kvm_hyp_code_start: | |||
| 353 | mrs x2, mdcr_el2 | 770 | mrs x2, mdcr_el2 |
| 354 | and x2, x2, #MDCR_EL2_HPMN_MASK | 771 | and x2, x2, #MDCR_EL2_HPMN_MASK |
| 355 | orr x2, x2, #(MDCR_EL2_TPM | MDCR_EL2_TPMCR) | 772 | orr x2, x2, #(MDCR_EL2_TPM | MDCR_EL2_TPMCR) |
| 773 | orr x2, x2, #(MDCR_EL2_TDRA | MDCR_EL2_TDOSA) | ||
| 774 | |||
| 775 | // Check for KVM_ARM64_DEBUG_DIRTY, and set debug to trap | ||
| 776 | // if not dirty. | ||
| 777 | ldr x3, [x0, #VCPU_DEBUG_FLAGS] | ||
| 778 | tbnz x3, #KVM_ARM64_DEBUG_DIRTY_SHIFT, 1f | ||
| 779 | orr x2, x2, #MDCR_EL2_TDA | ||
| 780 | 1: | ||
| 356 | msr mdcr_el2, x2 | 781 | msr mdcr_el2, x2 |
| 357 | .endm | 782 | .endm |
| 358 | 783 | ||
| @@ -379,100 +804,33 @@ __kvm_hyp_code_start: | |||
| 379 | .endm | 804 | .endm |
| 380 | 805 | ||
| 381 | /* | 806 | /* |
| 382 | * Save the VGIC CPU state into memory | 807 | * Call into the vgic backend for state saving |
| 383 | * x0: Register pointing to VCPU struct | ||
| 384 | * Do not corrupt x1!!! | ||
| 385 | */ | 808 | */ |
| 386 | .macro save_vgic_state | 809 | .macro save_vgic_state |
| 387 | /* Get VGIC VCTRL base into x2 */ | 810 | adr x24, __vgic_sr_vectors |
| 388 | ldr x2, [x0, #VCPU_KVM] | 811 | ldr x24, [x24, VGIC_SAVE_FN] |
| 389 | kern_hyp_va x2 | 812 | kern_hyp_va x24 |
| 390 | ldr x2, [x2, #KVM_VGIC_VCTRL] | 813 | blr x24 |
| 391 | kern_hyp_va x2 | 814 | mrs x24, hcr_el2 |
| 392 | cbz x2, 2f // disabled | 815 | mov x25, #HCR_INT_OVERRIDE |
| 393 | 816 | neg x25, x25 | |
| 394 | /* Compute the address of struct vgic_cpu */ | 817 | and x24, x24, x25 |
| 395 | add x3, x0, #VCPU_VGIC_CPU | 818 | msr hcr_el2, x24 |
| 396 | |||
| 397 | /* Save all interesting registers */ | ||
| 398 | ldr w4, [x2, #GICH_HCR] | ||
| 399 | ldr w5, [x2, #GICH_VMCR] | ||
| 400 | ldr w6, [x2, #GICH_MISR] | ||
| 401 | ldr w7, [x2, #GICH_EISR0] | ||
| 402 | ldr w8, [x2, #GICH_EISR1] | ||
| 403 | ldr w9, [x2, #GICH_ELRSR0] | ||
| 404 | ldr w10, [x2, #GICH_ELRSR1] | ||
| 405 | ldr w11, [x2, #GICH_APR] | ||
| 406 | CPU_BE( rev w4, w4 ) | ||
| 407 | CPU_BE( rev w5, w5 ) | ||
| 408 | CPU_BE( rev w6, w6 ) | ||
| 409 | CPU_BE( rev w7, w7 ) | ||
| 410 | CPU_BE( rev w8, w8 ) | ||
| 411 | CPU_BE( rev w9, w9 ) | ||
| 412 | CPU_BE( rev w10, w10 ) | ||
| 413 | CPU_BE( rev w11, w11 ) | ||
| 414 | |||
| 415 | str w4, [x3, #VGIC_CPU_HCR] | ||
| 416 | str w5, [x3, #VGIC_CPU_VMCR] | ||
| 417 | str w6, [x3, #VGIC_CPU_MISR] | ||
| 418 | str w7, [x3, #VGIC_CPU_EISR] | ||
| 419 | str w8, [x3, #(VGIC_CPU_EISR + 4)] | ||
| 420 | str w9, [x3, #VGIC_CPU_ELRSR] | ||
| 421 | str w10, [x3, #(VGIC_CPU_ELRSR + 4)] | ||
| 422 | str w11, [x3, #VGIC_CPU_APR] | ||
| 423 | |||
| 424 | /* Clear GICH_HCR */ | ||
| 425 | str wzr, [x2, #GICH_HCR] | ||
| 426 | |||
| 427 | /* Save list registers */ | ||
| 428 | add x2, x2, #GICH_LR0 | ||
| 429 | ldr w4, [x3, #VGIC_CPU_NR_LR] | ||
| 430 | add x3, x3, #VGIC_CPU_LR | ||
| 431 | 1: ldr w5, [x2], #4 | ||
| 432 | CPU_BE( rev w5, w5 ) | ||
| 433 | str w5, [x3], #4 | ||
| 434 | sub w4, w4, #1 | ||
| 435 | cbnz w4, 1b | ||
| 436 | 2: | ||
| 437 | .endm | 819 | .endm |
| 438 | 820 | ||
| 439 | /* | 821 | /* |
| 440 | * Restore the VGIC CPU state from memory | 822 | * Call into the vgic backend for state restoring |
| 441 | * x0: Register pointing to VCPU struct | ||
| 442 | */ | 823 | */ |
| 443 | .macro restore_vgic_state | 824 | .macro restore_vgic_state |
| 444 | /* Get VGIC VCTRL base into x2 */ | 825 | mrs x24, hcr_el2 |
| 445 | ldr x2, [x0, #VCPU_KVM] | 826 | ldr x25, [x0, #VCPU_IRQ_LINES] |
| 446 | kern_hyp_va x2 | 827 | orr x24, x24, #HCR_INT_OVERRIDE |
| 447 | ldr x2, [x2, #KVM_VGIC_VCTRL] | 828 | orr x24, x24, x25 |
| 448 | kern_hyp_va x2 | 829 | msr hcr_el2, x24 |
| 449 | cbz x2, 2f // disabled | 830 | adr x24, __vgic_sr_vectors |
| 450 | 831 | ldr x24, [x24, #VGIC_RESTORE_FN] | |
| 451 | /* Compute the address of struct vgic_cpu */ | 832 | kern_hyp_va x24 |
| 452 | add x3, x0, #VCPU_VGIC_CPU | 833 | blr x24 |
| 453 | |||
| 454 | /* We only restore a minimal set of registers */ | ||
| 455 | ldr w4, [x3, #VGIC_CPU_HCR] | ||
| 456 | ldr w5, [x3, #VGIC_CPU_VMCR] | ||
| 457 | ldr w6, [x3, #VGIC_CPU_APR] | ||
| 458 | CPU_BE( rev w4, w4 ) | ||
| 459 | CPU_BE( rev w5, w5 ) | ||
| 460 | CPU_BE( rev w6, w6 ) | ||
| 461 | |||
| 462 | str w4, [x2, #GICH_HCR] | ||
| 463 | str w5, [x2, #GICH_VMCR] | ||
| 464 | str w6, [x2, #GICH_APR] | ||
| 465 | |||
| 466 | /* Restore list registers */ | ||
| 467 | add x2, x2, #GICH_LR0 | ||
| 468 | ldr w4, [x3, #VGIC_CPU_NR_LR] | ||
| 469 | add x3, x3, #VGIC_CPU_LR | ||
| 470 | 1: ldr w5, [x3], #4 | ||
| 471 | CPU_BE( rev w5, w5 ) | ||
| 472 | str w5, [x2], #4 | ||
| 473 | sub w4, w4, #1 | ||
| 474 | cbnz w4, 1b | ||
| 475 | 2: | ||
| 476 | .endm | 834 | .endm |
| 477 | 835 | ||
| 478 | .macro save_timer_state | 836 | .macro save_timer_state |
| @@ -537,6 +895,14 @@ __restore_sysregs: | |||
| 537 | restore_sysregs | 895 | restore_sysregs |
| 538 | ret | 896 | ret |
| 539 | 897 | ||
| 898 | __save_debug: | ||
| 899 | save_debug | ||
| 900 | ret | ||
| 901 | |||
| 902 | __restore_debug: | ||
| 903 | restore_debug | ||
| 904 | ret | ||
| 905 | |||
| 540 | __save_fpsimd: | 906 | __save_fpsimd: |
| 541 | save_fpsimd | 907 | save_fpsimd |
| 542 | ret | 908 | ret |
| @@ -568,6 +934,9 @@ ENTRY(__kvm_vcpu_run) | |||
| 568 | bl __save_fpsimd | 934 | bl __save_fpsimd |
| 569 | bl __save_sysregs | 935 | bl __save_sysregs |
| 570 | 936 | ||
| 937 | compute_debug_state 1f | ||
| 938 | bl __save_debug | ||
| 939 | 1: | ||
| 571 | activate_traps | 940 | activate_traps |
| 572 | activate_vm | 941 | activate_vm |
| 573 | 942 | ||
| @@ -579,6 +948,10 @@ ENTRY(__kvm_vcpu_run) | |||
| 579 | 948 | ||
| 580 | bl __restore_sysregs | 949 | bl __restore_sysregs |
| 581 | bl __restore_fpsimd | 950 | bl __restore_fpsimd |
| 951 | |||
| 952 | skip_debug_state x3, 1f | ||
| 953 | bl __restore_debug | ||
| 954 | 1: | ||
| 582 | restore_guest_32bit_state | 955 | restore_guest_32bit_state |
| 583 | restore_guest_regs | 956 | restore_guest_regs |
| 584 | 957 | ||
| @@ -595,6 +968,10 @@ __kvm_vcpu_return: | |||
| 595 | save_guest_regs | 968 | save_guest_regs |
| 596 | bl __save_fpsimd | 969 | bl __save_fpsimd |
| 597 | bl __save_sysregs | 970 | bl __save_sysregs |
| 971 | |||
| 972 | skip_debug_state x3, 1f | ||
| 973 | bl __save_debug | ||
| 974 | 1: | ||
| 598 | save_guest_32bit_state | 975 | save_guest_32bit_state |
| 599 | 976 | ||
| 600 | save_timer_state | 977 | save_timer_state |
| @@ -609,6 +986,14 @@ __kvm_vcpu_return: | |||
| 609 | 986 | ||
| 610 | bl __restore_sysregs | 987 | bl __restore_sysregs |
| 611 | bl __restore_fpsimd | 988 | bl __restore_fpsimd |
| 989 | |||
| 990 | skip_debug_state x3, 1f | ||
| 991 | // Clear the dirty flag for the next run, as all the state has | ||
| 992 | // already been saved. Note that we nuke the whole 64bit word. | ||
| 993 | // If we ever add more flags, we'll have to be more careful... | ||
| 994 | str xzr, [x0, #VCPU_DEBUG_FLAGS] | ||
| 995 | bl __restore_debug | ||
| 996 | 1: | ||
| 612 | restore_host_regs | 997 | restore_host_regs |
| 613 | 998 | ||
| 614 | mov x0, x1 | 999 | mov x0, x1 |
| @@ -653,6 +1038,12 @@ ENTRY(__kvm_flush_vm_context) | |||
| 653 | ret | 1038 | ret |
| 654 | ENDPROC(__kvm_flush_vm_context) | 1039 | ENDPROC(__kvm_flush_vm_context) |
| 655 | 1040 | ||
| 1041 | // struct vgic_sr_vectors __vgi_sr_vectors; | ||
| 1042 | .align 3 | ||
| 1043 | ENTRY(__vgic_sr_vectors) | ||
| 1044 | .skip VGIC_SR_VECTOR_SZ | ||
| 1045 | ENDPROC(__vgic_sr_vectors) | ||
| 1046 | |||
| 656 | __kvm_hyp_panic: | 1047 | __kvm_hyp_panic: |
| 657 | // Guess the context by looking at VTTBR: | 1048 | // Guess the context by looking at VTTBR: |
| 658 | // If zero, then we're already a host. | 1049 | // If zero, then we're already a host. |
| @@ -830,7 +1221,7 @@ el1_trap: | |||
| 830 | mrs x2, far_el2 | 1221 | mrs x2, far_el2 |
| 831 | 1222 | ||
| 832 | 2: mrs x0, tpidr_el2 | 1223 | 2: mrs x0, tpidr_el2 |
| 833 | str x1, [x0, #VCPU_ESR_EL2] | 1224 | str w1, [x0, #VCPU_ESR_EL2] |
| 834 | str x2, [x0, #VCPU_FAR_EL2] | 1225 | str x2, [x0, #VCPU_FAR_EL2] |
| 835 | str x3, [x0, #VCPU_HPFAR_EL2] | 1226 | str x3, [x0, #VCPU_HPFAR_EL2] |
| 836 | 1227 | ||
| @@ -880,7 +1271,4 @@ ENTRY(__kvm_hyp_vector) | |||
| 880 | ventry el1_error_invalid // Error 32-bit EL1 | 1271 | ventry el1_error_invalid // Error 32-bit EL1 |
| 881 | ENDPROC(__kvm_hyp_vector) | 1272 | ENDPROC(__kvm_hyp_vector) |
| 882 | 1273 | ||
| 883 | __kvm_hyp_code_end: | ||
| 884 | .globl __kvm_hyp_code_end | ||
| 885 | |||
| 886 | .popsection | 1274 | .popsection |
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index c59a1bdab5eb..5805e7c4a4dd 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <asm/kvm_mmu.h> | 30 | #include <asm/kvm_mmu.h> |
| 31 | #include <asm/cacheflush.h> | 31 | #include <asm/cacheflush.h> |
| 32 | #include <asm/cputype.h> | 32 | #include <asm/cputype.h> |
| 33 | #include <asm/debug-monitors.h> | ||
| 33 | #include <trace/events/kvm.h> | 34 | #include <trace/events/kvm.h> |
| 34 | 35 | ||
| 35 | #include "sys_regs.h" | 36 | #include "sys_regs.h" |
| @@ -137,10 +138,11 @@ static bool access_vm_reg(struct kvm_vcpu *vcpu, | |||
| 137 | if (!p->is_aarch32) { | 138 | if (!p->is_aarch32) { |
| 138 | vcpu_sys_reg(vcpu, r->reg) = val; | 139 | vcpu_sys_reg(vcpu, r->reg) = val; |
| 139 | } else { | 140 | } else { |
| 140 | vcpu_cp15(vcpu, r->reg) = val & 0xffffffffUL; | ||
| 141 | if (!p->is_32bit) | 141 | if (!p->is_32bit) |
| 142 | vcpu_cp15(vcpu, r->reg + 1) = val >> 32; | 142 | vcpu_cp15_64_high(vcpu, r->reg) = val >> 32; |
| 143 | vcpu_cp15_64_low(vcpu, r->reg) = val & 0xffffffffUL; | ||
| 143 | } | 144 | } |
| 145 | |||
| 144 | return true; | 146 | return true; |
| 145 | } | 147 | } |
| 146 | 148 | ||
| @@ -163,18 +165,9 @@ static bool access_sctlr(struct kvm_vcpu *vcpu, | |||
| 163 | return true; | 165 | return true; |
| 164 | } | 166 | } |
| 165 | 167 | ||
| 166 | /* | 168 | static bool trap_raz_wi(struct kvm_vcpu *vcpu, |
| 167 | * We could trap ID_DFR0 and tell the guest we don't support performance | 169 | const struct sys_reg_params *p, |
| 168 | * monitoring. Unfortunately the patch to make the kernel check ID_DFR0 was | 170 | const struct sys_reg_desc *r) |
| 169 | * NAKed, so it will read the PMCR anyway. | ||
| 170 | * | ||
| 171 | * Therefore we tell the guest we have 0 counters. Unfortunately, we | ||
| 172 | * must always support PMCCNTR (the cycle counter): we just RAZ/WI for | ||
| 173 | * all PM registers, which doesn't crash the guest kernel at least. | ||
| 174 | */ | ||
| 175 | static bool pm_fake(struct kvm_vcpu *vcpu, | ||
| 176 | const struct sys_reg_params *p, | ||
| 177 | const struct sys_reg_desc *r) | ||
| 178 | { | 171 | { |
| 179 | if (p->is_write) | 172 | if (p->is_write) |
| 180 | return ignore_write(vcpu, p); | 173 | return ignore_write(vcpu, p); |
| @@ -182,6 +175,73 @@ static bool pm_fake(struct kvm_vcpu *vcpu, | |||
| 182 | return read_zero(vcpu, p); | 175 | return read_zero(vcpu, p); |
| 183 | } | 176 | } |
| 184 | 177 | ||
| 178 | static bool trap_oslsr_el1(struct kvm_vcpu *vcpu, | ||
| 179 | const struct sys_reg_params *p, | ||
| 180 | const struct sys_reg_desc *r) | ||
| 181 | { | ||
| 182 | if (p->is_write) { | ||
| 183 | return ignore_write(vcpu, p); | ||
| 184 | } else { | ||
| 185 | *vcpu_reg(vcpu, p->Rt) = (1 << 3); | ||
| 186 | return true; | ||
| 187 | } | ||
| 188 | } | ||
| 189 | |||
| 190 | static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu, | ||
| 191 | const struct sys_reg_params *p, | ||
| 192 | const struct sys_reg_desc *r) | ||
| 193 | { | ||
| 194 | if (p->is_write) { | ||
| 195 | return ignore_write(vcpu, p); | ||
| 196 | } else { | ||
| 197 | u32 val; | ||
| 198 | asm volatile("mrs %0, dbgauthstatus_el1" : "=r" (val)); | ||
| 199 | *vcpu_reg(vcpu, p->Rt) = val; | ||
| 200 | return true; | ||
| 201 | } | ||
| 202 | } | ||
| 203 | |||
| 204 | /* | ||
| 205 | * We want to avoid world-switching all the DBG registers all the | ||
| 206 | * time: | ||
| 207 | * | ||
| 208 | * - If we've touched any debug register, it is likely that we're | ||
| 209 | * going to touch more of them. It then makes sense to disable the | ||
| 210 | * traps and start doing the save/restore dance | ||
| 211 | * - If debug is active (DBG_MDSCR_KDE or DBG_MDSCR_MDE set), it is | ||
| 212 | * then mandatory to save/restore the registers, as the guest | ||
| 213 | * depends on them. | ||
| 214 | * | ||
| 215 | * For this, we use a DIRTY bit, indicating the guest has modified the | ||
| 216 | * debug registers, used as follow: | ||
| 217 | * | ||
| 218 | * On guest entry: | ||
| 219 | * - If the dirty bit is set (because we're coming back from trapping), | ||
| 220 | * disable the traps, save host registers, restore guest registers. | ||
| 221 | * - If debug is actively in use (DBG_MDSCR_KDE or DBG_MDSCR_MDE set), | ||
| 222 | * set the dirty bit, disable the traps, save host registers, | ||
| 223 | * restore guest registers. | ||
| 224 | * - Otherwise, enable the traps | ||
| 225 | * | ||
| 226 | * On guest exit: | ||
| 227 | * - If the dirty bit is set, save guest registers, restore host | ||
| 228 | * registers and clear the dirty bit. This ensure that the host can | ||
| 229 | * now use the debug registers. | ||
| 230 | */ | ||
| 231 | static bool trap_debug_regs(struct kvm_vcpu *vcpu, | ||
| 232 | const struct sys_reg_params *p, | ||
| 233 | const struct sys_reg_desc *r) | ||
| 234 | { | ||
| 235 | if (p->is_write) { | ||
| 236 | vcpu_sys_reg(vcpu, r->reg) = *vcpu_reg(vcpu, p->Rt); | ||
| 237 | vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY; | ||
| 238 | } else { | ||
| 239 | *vcpu_reg(vcpu, p->Rt) = vcpu_sys_reg(vcpu, r->reg); | ||
| 240 | } | ||
| 241 | |||
| 242 | return true; | ||
| 243 | } | ||
| 244 | |||
| 185 | static void reset_amair_el1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) | 245 | static void reset_amair_el1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) |
| 186 | { | 246 | { |
| 187 | u64 amair; | 247 | u64 amair; |
| @@ -198,9 +258,39 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) | |||
| 198 | vcpu_sys_reg(vcpu, MPIDR_EL1) = (1UL << 31) | (vcpu->vcpu_id & 0xff); | 258 | vcpu_sys_reg(vcpu, MPIDR_EL1) = (1UL << 31) | (vcpu->vcpu_id & 0xff); |
| 199 | } | 259 | } |
| 200 | 260 | ||
| 261 | /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */ | ||
| 262 | #define DBG_BCR_BVR_WCR_WVR_EL1(n) \ | ||
| 263 | /* DBGBVRn_EL1 */ \ | ||
| 264 | { Op0(0b10), Op1(0b000), CRn(0b0000), CRm((n)), Op2(0b100), \ | ||
| 265 | trap_debug_regs, reset_val, (DBGBVR0_EL1 + (n)), 0 }, \ | ||
| 266 | /* DBGBCRn_EL1 */ \ | ||
| 267 | { Op0(0b10), Op1(0b000), CRn(0b0000), CRm((n)), Op2(0b101), \ | ||
| 268 | trap_debug_regs, reset_val, (DBGBCR0_EL1 + (n)), 0 }, \ | ||
| 269 | /* DBGWVRn_EL1 */ \ | ||
| 270 | { Op0(0b10), Op1(0b000), CRn(0b0000), CRm((n)), Op2(0b110), \ | ||
| 271 | trap_debug_regs, reset_val, (DBGWVR0_EL1 + (n)), 0 }, \ | ||
| 272 | /* DBGWCRn_EL1 */ \ | ||
| 273 | { Op0(0b10), Op1(0b000), CRn(0b0000), CRm((n)), Op2(0b111), \ | ||
| 274 | trap_debug_regs, reset_val, (DBGWCR0_EL1 + (n)), 0 } | ||
| 275 | |||
| 201 | /* | 276 | /* |
| 202 | * Architected system registers. | 277 | * Architected system registers. |
| 203 | * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2 | 278 | * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2 |
| 279 | * | ||
| 280 | * We could trap ID_DFR0 and tell the guest we don't support performance | ||
| 281 | * monitoring. Unfortunately the patch to make the kernel check ID_DFR0 was | ||
| 282 | * NAKed, so it will read the PMCR anyway. | ||
| 283 | * | ||
| 284 | * Therefore we tell the guest we have 0 counters. Unfortunately, we | ||
| 285 | * must always support PMCCNTR (the cycle counter): we just RAZ/WI for | ||
| 286 | * all PM registers, which doesn't crash the guest kernel at least. | ||
| 287 | * | ||
| 288 | * Debug handling: We do trap most, if not all debug related system | ||
| 289 | * registers. The implementation is good enough to ensure that a guest | ||
| 290 | * can use these with minimal performance degradation. The drawback is | ||
| 291 | * that we don't implement any of the external debug, none of the | ||
| 292 | * OSlock protocol. This should be revisited if we ever encounter a | ||
| 293 | * more demanding guest... | ||
| 204 | */ | 294 | */ |
| 205 | static const struct sys_reg_desc sys_reg_descs[] = { | 295 | static const struct sys_reg_desc sys_reg_descs[] = { |
| 206 | /* DC ISW */ | 296 | /* DC ISW */ |
| @@ -213,12 +303,71 @@ static const struct sys_reg_desc sys_reg_descs[] = { | |||
| 213 | { Op0(0b01), Op1(0b000), CRn(0b0111), CRm(0b1110), Op2(0b010), | 303 | { Op0(0b01), Op1(0b000), CRn(0b0111), CRm(0b1110), Op2(0b010), |
| 214 | access_dcsw }, | 304 | access_dcsw }, |
| 215 | 305 | ||
| 306 | DBG_BCR_BVR_WCR_WVR_EL1(0), | ||
| 307 | DBG_BCR_BVR_WCR_WVR_EL1(1), | ||
| 308 | /* MDCCINT_EL1 */ | ||
| 309 | { Op0(0b10), Op1(0b000), CRn(0b0000), CRm(0b0010), Op2(0b000), | ||
| 310 | trap_debug_regs, reset_val, MDCCINT_EL1, 0 }, | ||
| 311 | /* MDSCR_EL1 */ | ||
| 312 | { Op0(0b10), Op1(0b000), CRn(0b0000), CRm(0b0010), Op2(0b010), | ||
| 313 | trap_debug_regs, reset_val, MDSCR_EL1, 0 }, | ||
| 314 | DBG_BCR_BVR_WCR_WVR_EL1(2), | ||
| 315 | DBG_BCR_BVR_WCR_WVR_EL1(3), | ||
| 316 | DBG_BCR_BVR_WCR_WVR_EL1(4), | ||
| 317 | DBG_BCR_BVR_WCR_WVR_EL1(5), | ||
| 318 | DBG_BCR_BVR_WCR_WVR_EL1(6), | ||
| 319 | DBG_BCR_BVR_WCR_WVR_EL1(7), | ||
| 320 | DBG_BCR_BVR_WCR_WVR_EL1(8), | ||
| 321 | DBG_BCR_BVR_WCR_WVR_EL1(9), | ||
| 322 | DBG_BCR_BVR_WCR_WVR_EL1(10), | ||
| 323 | DBG_BCR_BVR_WCR_WVR_EL1(11), | ||
| 324 | DBG_BCR_BVR_WCR_WVR_EL1(12), | ||
| 325 | DBG_BCR_BVR_WCR_WVR_EL1(13), | ||
| 326 | DBG_BCR_BVR_WCR_WVR_EL1(14), | ||
| 327 | DBG_BCR_BVR_WCR_WVR_EL1(15), | ||
| 328 | |||
| 329 | /* MDRAR_EL1 */ | ||
| 330 | { Op0(0b10), Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b000), | ||
| 331 | trap_raz_wi }, | ||
| 332 | /* OSLAR_EL1 */ | ||
| 333 | { Op0(0b10), Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b100), | ||
| 334 | trap_raz_wi }, | ||
| 335 | /* OSLSR_EL1 */ | ||
| 336 | { Op0(0b10), Op1(0b000), CRn(0b0001), CRm(0b0001), Op2(0b100), | ||
| 337 | trap_oslsr_el1 }, | ||
| 338 | /* OSDLR_EL1 */ | ||
| 339 | { Op0(0b10), Op1(0b000), CRn(0b0001), CRm(0b0011), Op2(0b100), | ||
| 340 | trap_raz_wi }, | ||
| 341 | /* DBGPRCR_EL1 */ | ||
| 342 | { Op0(0b10), Op1(0b000), CRn(0b0001), CRm(0b0100), Op2(0b100), | ||
| 343 | trap_raz_wi }, | ||
| 344 | /* DBGCLAIMSET_EL1 */ | ||
| 345 | { Op0(0b10), Op1(0b000), CRn(0b0111), CRm(0b1000), Op2(0b110), | ||
| 346 | trap_raz_wi }, | ||
| 347 | /* DBGCLAIMCLR_EL1 */ | ||
| 348 | { Op0(0b10), Op1(0b000), CRn(0b0111), CRm(0b1001), Op2(0b110), | ||
| 349 | trap_raz_wi }, | ||
| 350 | /* DBGAUTHSTATUS_EL1 */ | ||
| 351 | { Op0(0b10), Op1(0b000), CRn(0b0111), CRm(0b1110), Op2(0b110), | ||
| 352 | trap_dbgauthstatus_el1 }, | ||
| 353 | |||
| 216 | /* TEECR32_EL1 */ | 354 | /* TEECR32_EL1 */ |
| 217 | { Op0(0b10), Op1(0b010), CRn(0b0000), CRm(0b0000), Op2(0b000), | 355 | { Op0(0b10), Op1(0b010), CRn(0b0000), CRm(0b0000), Op2(0b000), |
| 218 | NULL, reset_val, TEECR32_EL1, 0 }, | 356 | NULL, reset_val, TEECR32_EL1, 0 }, |
| 219 | /* TEEHBR32_EL1 */ | 357 | /* TEEHBR32_EL1 */ |
| 220 | { Op0(0b10), Op1(0b010), CRn(0b0001), CRm(0b0000), Op2(0b000), | 358 | { Op0(0b10), Op1(0b010), CRn(0b0001), CRm(0b0000), Op2(0b000), |
| 221 | NULL, reset_val, TEEHBR32_EL1, 0 }, | 359 | NULL, reset_val, TEEHBR32_EL1, 0 }, |
| 360 | |||
| 361 | /* MDCCSR_EL1 */ | ||
| 362 | { Op0(0b10), Op1(0b011), CRn(0b0000), CRm(0b0001), Op2(0b000), | ||
| 363 | trap_raz_wi }, | ||
| 364 | /* DBGDTR_EL0 */ | ||
| 365 | { Op0(0b10), Op1(0b011), CRn(0b0000), CRm(0b0100), Op2(0b000), | ||
| 366 | trap_raz_wi }, | ||
| 367 | /* DBGDTR[TR]X_EL0 */ | ||
| 368 | { Op0(0b10), Op1(0b011), CRn(0b0000), CRm(0b0101), Op2(0b000), | ||
| 369 | trap_raz_wi }, | ||
| 370 | |||
| 222 | /* DBGVCR32_EL2 */ | 371 | /* DBGVCR32_EL2 */ |
| 223 | { Op0(0b10), Op1(0b100), CRn(0b0000), CRm(0b0111), Op2(0b000), | 372 | { Op0(0b10), Op1(0b100), CRn(0b0000), CRm(0b0111), Op2(0b000), |
| 224 | NULL, reset_val, DBGVCR32_EL2, 0 }, | 373 | NULL, reset_val, DBGVCR32_EL2, 0 }, |
| @@ -260,10 +409,10 @@ static const struct sys_reg_desc sys_reg_descs[] = { | |||
| 260 | 409 | ||
| 261 | /* PMINTENSET_EL1 */ | 410 | /* PMINTENSET_EL1 */ |
| 262 | { Op0(0b11), Op1(0b000), CRn(0b1001), CRm(0b1110), Op2(0b001), | 411 | { Op0(0b11), Op1(0b000), CRn(0b1001), CRm(0b1110), Op2(0b001), |
| 263 | pm_fake }, | 412 | trap_raz_wi }, |
| 264 | /* PMINTENCLR_EL1 */ | 413 | /* PMINTENCLR_EL1 */ |
| 265 | { Op0(0b11), Op1(0b000), CRn(0b1001), CRm(0b1110), Op2(0b010), | 414 | { Op0(0b11), Op1(0b000), CRn(0b1001), CRm(0b1110), Op2(0b010), |
| 266 | pm_fake }, | 415 | trap_raz_wi }, |
| 267 | 416 | ||
| 268 | /* MAIR_EL1 */ | 417 | /* MAIR_EL1 */ |
| 269 | { Op0(0b11), Op1(0b000), CRn(0b1010), CRm(0b0010), Op2(0b000), | 418 | { Op0(0b11), Op1(0b000), CRn(0b1010), CRm(0b0010), Op2(0b000), |
| @@ -292,43 +441,43 @@ static const struct sys_reg_desc sys_reg_descs[] = { | |||
| 292 | 441 | ||
| 293 | /* PMCR_EL0 */ | 442 | /* PMCR_EL0 */ |
| 294 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b000), | 443 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b000), |
| 295 | pm_fake }, | 444 | trap_raz_wi }, |
| 296 | /* PMCNTENSET_EL0 */ | 445 | /* PMCNTENSET_EL0 */ |
| 297 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b001), | 446 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b001), |
| 298 | pm_fake }, | 447 | trap_raz_wi }, |
| 299 | /* PMCNTENCLR_EL0 */ | 448 | /* PMCNTENCLR_EL0 */ |
| 300 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b010), | 449 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b010), |
| 301 | pm_fake }, | 450 | trap_raz_wi }, |
| 302 | /* PMOVSCLR_EL0 */ | 451 | /* PMOVSCLR_EL0 */ |
| 303 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b011), | 452 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b011), |
| 304 | pm_fake }, | 453 | trap_raz_wi }, |
| 305 | /* PMSWINC_EL0 */ | 454 | /* PMSWINC_EL0 */ |
| 306 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b100), | 455 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b100), |
| 307 | pm_fake }, | 456 | trap_raz_wi }, |
| 308 | /* PMSELR_EL0 */ | 457 | /* PMSELR_EL0 */ |
| 309 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b101), | 458 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b101), |
| 310 | pm_fake }, | 459 | trap_raz_wi }, |
| 311 | /* PMCEID0_EL0 */ | 460 | /* PMCEID0_EL0 */ |
| 312 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b110), | 461 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b110), |
| 313 | pm_fake }, | 462 | trap_raz_wi }, |
| 314 | /* PMCEID1_EL0 */ | 463 | /* PMCEID1_EL0 */ |
| 315 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b111), | 464 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b111), |
| 316 | pm_fake }, | 465 | trap_raz_wi }, |
| 317 | /* PMCCNTR_EL0 */ | 466 | /* PMCCNTR_EL0 */ |
| 318 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b000), | 467 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b000), |
| 319 | pm_fake }, | 468 | trap_raz_wi }, |
| 320 | /* PMXEVTYPER_EL0 */ | 469 | /* PMXEVTYPER_EL0 */ |
| 321 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b001), | 470 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b001), |
| 322 | pm_fake }, | 471 | trap_raz_wi }, |
| 323 | /* PMXEVCNTR_EL0 */ | 472 | /* PMXEVCNTR_EL0 */ |
| 324 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b010), | 473 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b010), |
| 325 | pm_fake }, | 474 | trap_raz_wi }, |
| 326 | /* PMUSERENR_EL0 */ | 475 | /* PMUSERENR_EL0 */ |
| 327 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b000), | 476 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b000), |
| 328 | pm_fake }, | 477 | trap_raz_wi }, |
| 329 | /* PMOVSSET_EL0 */ | 478 | /* PMOVSSET_EL0 */ |
| 330 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b011), | 479 | { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b011), |
| 331 | pm_fake }, | 480 | trap_raz_wi }, |
| 332 | 481 | ||
| 333 | /* TPIDR_EL0 */ | 482 | /* TPIDR_EL0 */ |
| 334 | { Op0(0b11), Op1(0b011), CRn(0b1101), CRm(0b0000), Op2(0b010), | 483 | { Op0(0b11), Op1(0b011), CRn(0b1101), CRm(0b0000), Op2(0b010), |
| @@ -348,13 +497,161 @@ static const struct sys_reg_desc sys_reg_descs[] = { | |||
| 348 | NULL, reset_val, FPEXC32_EL2, 0x70 }, | 497 | NULL, reset_val, FPEXC32_EL2, 0x70 }, |
| 349 | }; | 498 | }; |
| 350 | 499 | ||
| 500 | static bool trap_dbgidr(struct kvm_vcpu *vcpu, | ||
| 501 | const struct sys_reg_params *p, | ||
| 502 | const struct sys_reg_desc *r) | ||
| 503 | { | ||
| 504 | if (p->is_write) { | ||
| 505 | return ignore_write(vcpu, p); | ||
| 506 | } else { | ||
| 507 | u64 dfr = read_cpuid(ID_AA64DFR0_EL1); | ||
| 508 | u64 pfr = read_cpuid(ID_AA64PFR0_EL1); | ||
| 509 | u32 el3 = !!((pfr >> 12) & 0xf); | ||
| 510 | |||
| 511 | *vcpu_reg(vcpu, p->Rt) = ((((dfr >> 20) & 0xf) << 28) | | ||
| 512 | (((dfr >> 12) & 0xf) << 24) | | ||
| 513 | (((dfr >> 28) & 0xf) << 20) | | ||
| 514 | (6 << 16) | (el3 << 14) | (el3 << 12)); | ||
| 515 | return true; | ||
| 516 | } | ||
| 517 | } | ||
| 518 | |||
| 519 | static bool trap_debug32(struct kvm_vcpu *vcpu, | ||
| 520 | const struct sys_reg_params *p, | ||
| 521 | const struct sys_reg_desc *r) | ||
| 522 | { | ||
| 523 | if (p->is_write) { | ||
| 524 | vcpu_cp14(vcpu, r->reg) = *vcpu_reg(vcpu, p->Rt); | ||
| 525 | vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY; | ||
| 526 | } else { | ||
| 527 | *vcpu_reg(vcpu, p->Rt) = vcpu_cp14(vcpu, r->reg); | ||
| 528 | } | ||
| 529 | |||
| 530 | return true; | ||
| 531 | } | ||
| 532 | |||
| 533 | #define DBG_BCR_BVR_WCR_WVR(n) \ | ||
| 534 | /* DBGBVRn */ \ | ||
| 535 | { Op1( 0), CRn( 0), CRm((n)), Op2( 4), trap_debug32, \ | ||
| 536 | NULL, (cp14_DBGBVR0 + (n) * 2) }, \ | ||
| 537 | /* DBGBCRn */ \ | ||
| 538 | { Op1( 0), CRn( 0), CRm((n)), Op2( 5), trap_debug32, \ | ||
| 539 | NULL, (cp14_DBGBCR0 + (n) * 2) }, \ | ||
| 540 | /* DBGWVRn */ \ | ||
| 541 | { Op1( 0), CRn( 0), CRm((n)), Op2( 6), trap_debug32, \ | ||
| 542 | NULL, (cp14_DBGWVR0 + (n) * 2) }, \ | ||
| 543 | /* DBGWCRn */ \ | ||
| 544 | { Op1( 0), CRn( 0), CRm((n)), Op2( 7), trap_debug32, \ | ||
| 545 | NULL, (cp14_DBGWCR0 + (n) * 2) } | ||
| 546 | |||
| 547 | #define DBGBXVR(n) \ | ||
| 548 | { Op1( 0), CRn( 1), CRm((n)), Op2( 1), trap_debug32, \ | ||
| 549 | NULL, cp14_DBGBXVR0 + n * 2 } | ||
| 550 | |||
| 551 | /* | ||
| 552 | * Trapped cp14 registers. We generally ignore most of the external | ||
| 553 | * debug, on the principle that they don't really make sense to a | ||
| 554 | * guest. Revisit this one day, whould this principle change. | ||
| 555 | */ | ||
| 556 | static const struct sys_reg_desc cp14_regs[] = { | ||
| 557 | /* DBGIDR */ | ||
| 558 | { Op1( 0), CRn( 0), CRm( 0), Op2( 0), trap_dbgidr }, | ||
| 559 | /* DBGDTRRXext */ | ||
| 560 | { Op1( 0), CRn( 0), CRm( 0), Op2( 2), trap_raz_wi }, | ||
| 561 | |||
| 562 | DBG_BCR_BVR_WCR_WVR(0), | ||
| 563 | /* DBGDSCRint */ | ||
| 564 | { Op1( 0), CRn( 0), CRm( 1), Op2( 0), trap_raz_wi }, | ||
| 565 | DBG_BCR_BVR_WCR_WVR(1), | ||
| 566 | /* DBGDCCINT */ | ||
| 567 | { Op1( 0), CRn( 0), CRm( 2), Op2( 0), trap_debug32 }, | ||
| 568 | /* DBGDSCRext */ | ||
| 569 | { Op1( 0), CRn( 0), CRm( 2), Op2( 2), trap_debug32 }, | ||
| 570 | DBG_BCR_BVR_WCR_WVR(2), | ||
| 571 | /* DBGDTR[RT]Xint */ | ||
| 572 | { Op1( 0), CRn( 0), CRm( 3), Op2( 0), trap_raz_wi }, | ||
| 573 | /* DBGDTR[RT]Xext */ | ||
| 574 | { Op1( 0), CRn( 0), CRm( 3), Op2( 2), trap_raz_wi }, | ||
| 575 | DBG_BCR_BVR_WCR_WVR(3), | ||
| 576 | DBG_BCR_BVR_WCR_WVR(4), | ||
| 577 | DBG_BCR_BVR_WCR_WVR(5), | ||
| 578 | /* DBGWFAR */ | ||
| 579 | { Op1( 0), CRn( 0), CRm( 6), Op2( 0), trap_raz_wi }, | ||
| 580 | /* DBGOSECCR */ | ||
| 581 | { Op1( 0), CRn( 0), CRm( 6), Op2( 2), trap_raz_wi }, | ||
| 582 | DBG_BCR_BVR_WCR_WVR(6), | ||
| 583 | /* DBGVCR */ | ||
| 584 | { Op1( 0), CRn( 0), CRm( 7), Op2( 0), trap_debug32 }, | ||
| 585 | DBG_BCR_BVR_WCR_WVR(7), | ||
| 586 | DBG_BCR_BVR_WCR_WVR(8), | ||
| 587 | DBG_BCR_BVR_WCR_WVR(9), | ||
| 588 | DBG_BCR_BVR_WCR_WVR(10), | ||
| 589 | DBG_BCR_BVR_WCR_WVR(11), | ||
| 590 | DBG_BCR_BVR_WCR_WVR(12), | ||
| 591 | DBG_BCR_BVR_WCR_WVR(13), | ||
| 592 | DBG_BCR_BVR_WCR_WVR(14), | ||
| 593 | DBG_BCR_BVR_WCR_WVR(15), | ||
| 594 | |||
| 595 | /* DBGDRAR (32bit) */ | ||
| 596 | { Op1( 0), CRn( 1), CRm( 0), Op2( 0), trap_raz_wi }, | ||
| 597 | |||
| 598 | DBGBXVR(0), | ||
| 599 | /* DBGOSLAR */ | ||
| 600 | { Op1( 0), CRn( 1), CRm( 0), Op2( 4), trap_raz_wi }, | ||
| 601 | DBGBXVR(1), | ||
| 602 | /* DBGOSLSR */ | ||
| 603 | { Op1( 0), CRn( 1), CRm( 1), Op2( 4), trap_oslsr_el1 }, | ||
| 604 | DBGBXVR(2), | ||
| 605 | DBGBXVR(3), | ||
| 606 | /* DBGOSDLR */ | ||
| 607 | { Op1( 0), CRn( 1), CRm( 3), Op2( 4), trap_raz_wi }, | ||
| 608 | DBGBXVR(4), | ||
| 609 | /* DBGPRCR */ | ||
| 610 | { Op1( 0), CRn( 1), CRm( 4), Op2( 4), trap_raz_wi }, | ||
| 611 | DBGBXVR(5), | ||
| 612 | DBGBXVR(6), | ||
| 613 | DBGBXVR(7), | ||
| 614 | DBGBXVR(8), | ||
| 615 | DBGBXVR(9), | ||
| 616 | DBGBXVR(10), | ||
| 617 | DBGBXVR(11), | ||
| 618 | DBGBXVR(12), | ||
| 619 | DBGBXVR(13), | ||
| 620 | DBGBXVR(14), | ||
| 621 | DBGBXVR(15), | ||
| 622 | |||
| 623 | /* DBGDSAR (32bit) */ | ||
| 624 | { Op1( 0), CRn( 2), CRm( 0), Op2( 0), trap_raz_wi }, | ||
| 625 | |||
| 626 | /* DBGDEVID2 */ | ||
| 627 | { Op1( 0), CRn( 7), CRm( 0), Op2( 7), trap_raz_wi }, | ||
| 628 | /* DBGDEVID1 */ | ||
| 629 | { Op1( 0), CRn( 7), CRm( 1), Op2( 7), trap_raz_wi }, | ||
| 630 | /* DBGDEVID */ | ||
| 631 | { Op1( 0), CRn( 7), CRm( 2), Op2( 7), trap_raz_wi }, | ||
| 632 | /* DBGCLAIMSET */ | ||
| 633 | { Op1( 0), CRn( 7), CRm( 8), Op2( 6), trap_raz_wi }, | ||
| 634 | /* DBGCLAIMCLR */ | ||
| 635 | { Op1( 0), CRn( 7), CRm( 9), Op2( 6), trap_raz_wi }, | ||
| 636 | /* DBGAUTHSTATUS */ | ||
| 637 | { Op1( 0), CRn( 7), CRm(14), Op2( 6), trap_dbgauthstatus_el1 }, | ||
| 638 | }; | ||
| 639 | |||
| 640 | /* Trapped cp14 64bit registers */ | ||
| 641 | static const struct sys_reg_desc cp14_64_regs[] = { | ||
| 642 | /* DBGDRAR (64bit) */ | ||
| 643 | { Op1( 0), CRm( 1), .access = trap_raz_wi }, | ||
| 644 | |||
| 645 | /* DBGDSAR (64bit) */ | ||
| 646 | { Op1( 0), CRm( 2), .access = trap_raz_wi }, | ||
| 647 | }; | ||
| 648 | |||
| 351 | /* | 649 | /* |
| 352 | * Trapped cp15 registers. TTBR0/TTBR1 get a double encoding, | 650 | * Trapped cp15 registers. TTBR0/TTBR1 get a double encoding, |
| 353 | * depending on the way they are accessed (as a 32bit or a 64bit | 651 | * depending on the way they are accessed (as a 32bit or a 64bit |
| 354 | * register). | 652 | * register). |
| 355 | */ | 653 | */ |
| 356 | static const struct sys_reg_desc cp15_regs[] = { | 654 | static const struct sys_reg_desc cp15_regs[] = { |
| 357 | { Op1( 0), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR0 }, | ||
| 358 | { Op1( 0), CRn( 1), CRm( 0), Op2( 0), access_sctlr, NULL, c1_SCTLR }, | 655 | { Op1( 0), CRn( 1), CRm( 0), Op2( 0), access_sctlr, NULL, c1_SCTLR }, |
| 359 | { Op1( 0), CRn( 2), CRm( 0), Op2( 0), access_vm_reg, NULL, c2_TTBR0 }, | 656 | { Op1( 0), CRn( 2), CRm( 0), Op2( 0), access_vm_reg, NULL, c2_TTBR0 }, |
| 360 | { Op1( 0), CRn( 2), CRm( 0), Op2( 1), access_vm_reg, NULL, c2_TTBR1 }, | 657 | { Op1( 0), CRn( 2), CRm( 0), Op2( 1), access_vm_reg, NULL, c2_TTBR1 }, |
| @@ -374,26 +671,30 @@ static const struct sys_reg_desc cp15_regs[] = { | |||
| 374 | { Op1( 0), CRn( 7), CRm(10), Op2( 2), access_dcsw }, | 671 | { Op1( 0), CRn( 7), CRm(10), Op2( 2), access_dcsw }, |
| 375 | { Op1( 0), CRn( 7), CRm(14), Op2( 2), access_dcsw }, | 672 | { Op1( 0), CRn( 7), CRm(14), Op2( 2), access_dcsw }, |
| 376 | 673 | ||
| 377 | { Op1( 0), CRn( 9), CRm(12), Op2( 0), pm_fake }, | 674 | /* PMU */ |
| 378 | { Op1( 0), CRn( 9), CRm(12), Op2( 1), pm_fake }, | 675 | { Op1( 0), CRn( 9), CRm(12), Op2( 0), trap_raz_wi }, |
| 379 | { Op1( 0), CRn( 9), CRm(12), Op2( 2), pm_fake }, | 676 | { Op1( 0), CRn( 9), CRm(12), Op2( 1), trap_raz_wi }, |
| 380 | { Op1( 0), CRn( 9), CRm(12), Op2( 3), pm_fake }, | 677 | { Op1( 0), CRn( 9), CRm(12), Op2( 2), trap_raz_wi }, |
| 381 | { Op1( 0), CRn( 9), CRm(12), Op2( 5), pm_fake }, | 678 | { Op1( 0), CRn( 9), CRm(12), Op2( 3), trap_raz_wi }, |
| 382 | { Op1( 0), CRn( 9), CRm(12), Op2( 6), pm_fake }, | 679 | { Op1( 0), CRn( 9), CRm(12), Op2( 5), trap_raz_wi }, |
| 383 | { Op1( 0), CRn( 9), CRm(12), Op2( 7), pm_fake }, | 680 | { Op1( 0), CRn( 9), CRm(12), Op2( 6), trap_raz_wi }, |
| 384 | { Op1( 0), CRn( 9), CRm(13), Op2( 0), pm_fake }, | 681 | { Op1( 0), CRn( 9), CRm(12), Op2( 7), trap_raz_wi }, |
| 385 | { Op1( 0), CRn( 9), CRm(13), Op2( 1), pm_fake }, | 682 | { Op1( 0), CRn( 9), CRm(13), Op2( 0), trap_raz_wi }, |
| 386 | { Op1( 0), CRn( 9), CRm(13), Op2( 2), pm_fake }, | 683 | { Op1( 0), CRn( 9), CRm(13), Op2( 1), trap_raz_wi }, |
| 387 | { Op1( 0), CRn( 9), CRm(14), Op2( 0), pm_fake }, | 684 | { Op1( 0), CRn( 9), CRm(13), Op2( 2), trap_raz_wi }, |
| 388 | { Op1( 0), CRn( 9), CRm(14), Op2( 1), pm_fake }, | 685 | { Op1( 0), CRn( 9), CRm(14), Op2( 0), trap_raz_wi }, |
| 389 | { Op1( 0), CRn( 9), CRm(14), Op2( 2), pm_fake }, | 686 | { Op1( 0), CRn( 9), CRm(14), Op2( 1), trap_raz_wi }, |
| 687 | { Op1( 0), CRn( 9), CRm(14), Op2( 2), trap_raz_wi }, | ||
| 390 | 688 | ||
| 391 | { Op1( 0), CRn(10), CRm( 2), Op2( 0), access_vm_reg, NULL, c10_PRRR }, | 689 | { Op1( 0), CRn(10), CRm( 2), Op2( 0), access_vm_reg, NULL, c10_PRRR }, |
| 392 | { Op1( 0), CRn(10), CRm( 2), Op2( 1), access_vm_reg, NULL, c10_NMRR }, | 690 | { Op1( 0), CRn(10), CRm( 2), Op2( 1), access_vm_reg, NULL, c10_NMRR }, |
| 393 | { Op1( 0), CRn(10), CRm( 3), Op2( 0), access_vm_reg, NULL, c10_AMAIR0 }, | 691 | { Op1( 0), CRn(10), CRm( 3), Op2( 0), access_vm_reg, NULL, c10_AMAIR0 }, |
| 394 | { Op1( 0), CRn(10), CRm( 3), Op2( 1), access_vm_reg, NULL, c10_AMAIR1 }, | 692 | { Op1( 0), CRn(10), CRm( 3), Op2( 1), access_vm_reg, NULL, c10_AMAIR1 }, |
| 395 | { Op1( 0), CRn(13), CRm( 0), Op2( 1), access_vm_reg, NULL, c13_CID }, | 693 | { Op1( 0), CRn(13), CRm( 0), Op2( 1), access_vm_reg, NULL, c13_CID }, |
| 694 | }; | ||
| 396 | 695 | ||
| 696 | static const struct sys_reg_desc cp15_64_regs[] = { | ||
| 697 | { Op1( 0), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR0 }, | ||
| 397 | { Op1( 1), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR1 }, | 698 | { Op1( 1), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR1 }, |
| 398 | }; | 699 | }; |
| 399 | 700 | ||
| @@ -454,26 +755,29 @@ int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
| 454 | return 1; | 755 | return 1; |
| 455 | } | 756 | } |
| 456 | 757 | ||
| 457 | int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run) | 758 | /* |
| 458 | { | 759 | * emulate_cp -- tries to match a sys_reg access in a handling table, and |
| 459 | kvm_inject_undefined(vcpu); | 760 | * call the corresponding trap handler. |
| 460 | return 1; | 761 | * |
| 461 | } | 762 | * @params: pointer to the descriptor of the access |
| 462 | 763 | * @table: array of trap descriptors | |
| 463 | static void emulate_cp15(struct kvm_vcpu *vcpu, | 764 | * @num: size of the trap descriptor array |
| 464 | const struct sys_reg_params *params) | 765 | * |
| 766 | * Return 0 if the access has been handled, and -1 if not. | ||
| 767 | */ | ||
| 768 | static int emulate_cp(struct kvm_vcpu *vcpu, | ||
| 769 | const struct sys_reg_params *params, | ||
| 770 | const struct sys_reg_desc *table, | ||
| 771 | size_t num) | ||
| 465 | { | 772 | { |
| 466 | size_t num; | 773 | const struct sys_reg_desc *r; |
| 467 | const struct sys_reg_desc *table, *r; | ||
| 468 | 774 | ||
| 469 | table = get_target_table(vcpu->arch.target, false, &num); | 775 | if (!table) |
| 776 | return -1; /* Not handled */ | ||
| 470 | 777 | ||
| 471 | /* Search target-specific then generic table. */ | ||
| 472 | r = find_reg(params, table, num); | 778 | r = find_reg(params, table, num); |
| 473 | if (!r) | ||
| 474 | r = find_reg(params, cp15_regs, ARRAY_SIZE(cp15_regs)); | ||
| 475 | 779 | ||
| 476 | if (likely(r)) { | 780 | if (r) { |
| 477 | /* | 781 | /* |
| 478 | * Not having an accessor means that we have | 782 | * Not having an accessor means that we have |
| 479 | * configured a trap that we don't know how to | 783 | * configured a trap that we don't know how to |
| @@ -485,22 +789,51 @@ static void emulate_cp15(struct kvm_vcpu *vcpu, | |||
| 485 | if (likely(r->access(vcpu, params, r))) { | 789 | if (likely(r->access(vcpu, params, r))) { |
| 486 | /* Skip instruction, since it was emulated */ | 790 | /* Skip instruction, since it was emulated */ |
| 487 | kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); | 791 | kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); |
| 488 | return; | ||
| 489 | } | 792 | } |
| 490 | /* If access function fails, it should complain. */ | 793 | |
| 794 | /* Handled */ | ||
| 795 | return 0; | ||
| 491 | } | 796 | } |
| 492 | 797 | ||
| 493 | kvm_err("Unsupported guest CP15 access at: %08lx\n", *vcpu_pc(vcpu)); | 798 | /* Not handled */ |
| 799 | return -1; | ||
| 800 | } | ||
| 801 | |||
| 802 | static void unhandled_cp_access(struct kvm_vcpu *vcpu, | ||
| 803 | struct sys_reg_params *params) | ||
| 804 | { | ||
| 805 | u8 hsr_ec = kvm_vcpu_trap_get_class(vcpu); | ||
| 806 | int cp; | ||
| 807 | |||
| 808 | switch(hsr_ec) { | ||
| 809 | case ESR_EL2_EC_CP15_32: | ||
| 810 | case ESR_EL2_EC_CP15_64: | ||
| 811 | cp = 15; | ||
| 812 | break; | ||
| 813 | case ESR_EL2_EC_CP14_MR: | ||
| 814 | case ESR_EL2_EC_CP14_64: | ||
| 815 | cp = 14; | ||
| 816 | break; | ||
| 817 | default: | ||
| 818 | WARN_ON((cp = -1)); | ||
| 819 | } | ||
| 820 | |||
| 821 | kvm_err("Unsupported guest CP%d access at: %08lx\n", | ||
| 822 | cp, *vcpu_pc(vcpu)); | ||
| 494 | print_sys_reg_instr(params); | 823 | print_sys_reg_instr(params); |
| 495 | kvm_inject_undefined(vcpu); | 824 | kvm_inject_undefined(vcpu); |
| 496 | } | 825 | } |
| 497 | 826 | ||
| 498 | /** | 827 | /** |
| 499 | * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access | 828 | * kvm_handle_cp_64 -- handles a mrrc/mcrr trap on a guest CP15 access |
| 500 | * @vcpu: The VCPU pointer | 829 | * @vcpu: The VCPU pointer |
| 501 | * @run: The kvm_run struct | 830 | * @run: The kvm_run struct |
| 502 | */ | 831 | */ |
| 503 | int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run) | 832 | static int kvm_handle_cp_64(struct kvm_vcpu *vcpu, |
| 833 | const struct sys_reg_desc *global, | ||
| 834 | size_t nr_global, | ||
| 835 | const struct sys_reg_desc *target_specific, | ||
| 836 | size_t nr_specific) | ||
| 504 | { | 837 | { |
| 505 | struct sys_reg_params params; | 838 | struct sys_reg_params params; |
| 506 | u32 hsr = kvm_vcpu_get_hsr(vcpu); | 839 | u32 hsr = kvm_vcpu_get_hsr(vcpu); |
| @@ -529,8 +862,14 @@ int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
| 529 | *vcpu_reg(vcpu, params.Rt) = val; | 862 | *vcpu_reg(vcpu, params.Rt) = val; |
| 530 | } | 863 | } |
| 531 | 864 | ||
| 532 | emulate_cp15(vcpu, ¶ms); | 865 | if (!emulate_cp(vcpu, ¶ms, target_specific, nr_specific)) |
| 866 | goto out; | ||
| 867 | if (!emulate_cp(vcpu, ¶ms, global, nr_global)) | ||
| 868 | goto out; | ||
| 533 | 869 | ||
| 870 | unhandled_cp_access(vcpu, ¶ms); | ||
| 871 | |||
| 872 | out: | ||
| 534 | /* Do the opposite hack for the read side */ | 873 | /* Do the opposite hack for the read side */ |
| 535 | if (!params.is_write) { | 874 | if (!params.is_write) { |
| 536 | u64 val = *vcpu_reg(vcpu, params.Rt); | 875 | u64 val = *vcpu_reg(vcpu, params.Rt); |
| @@ -546,7 +885,11 @@ int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
| 546 | * @vcpu: The VCPU pointer | 885 | * @vcpu: The VCPU pointer |
| 547 | * @run: The kvm_run struct | 886 | * @run: The kvm_run struct |
| 548 | */ | 887 | */ |
| 549 | int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run) | 888 | static int kvm_handle_cp_32(struct kvm_vcpu *vcpu, |
| 889 | const struct sys_reg_desc *global, | ||
| 890 | size_t nr_global, | ||
| 891 | const struct sys_reg_desc *target_specific, | ||
| 892 | size_t nr_specific) | ||
| 550 | { | 893 | { |
| 551 | struct sys_reg_params params; | 894 | struct sys_reg_params params; |
| 552 | u32 hsr = kvm_vcpu_get_hsr(vcpu); | 895 | u32 hsr = kvm_vcpu_get_hsr(vcpu); |
| @@ -561,10 +904,51 @@ int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
| 561 | params.Op1 = (hsr >> 14) & 0x7; | 904 | params.Op1 = (hsr >> 14) & 0x7; |
| 562 | params.Op2 = (hsr >> 17) & 0x7; | 905 | params.Op2 = (hsr >> 17) & 0x7; |
| 563 | 906 | ||
| 564 | emulate_cp15(vcpu, ¶ms); | 907 | if (!emulate_cp(vcpu, ¶ms, target_specific, nr_specific)) |
| 908 | return 1; | ||
| 909 | if (!emulate_cp(vcpu, ¶ms, global, nr_global)) | ||
| 910 | return 1; | ||
| 911 | |||
| 912 | unhandled_cp_access(vcpu, ¶ms); | ||
| 565 | return 1; | 913 | return 1; |
| 566 | } | 914 | } |
| 567 | 915 | ||
| 916 | int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run) | ||
| 917 | { | ||
| 918 | const struct sys_reg_desc *target_specific; | ||
| 919 | size_t num; | ||
| 920 | |||
| 921 | target_specific = get_target_table(vcpu->arch.target, false, &num); | ||
| 922 | return kvm_handle_cp_64(vcpu, | ||
| 923 | cp15_64_regs, ARRAY_SIZE(cp15_64_regs), | ||
| 924 | target_specific, num); | ||
| 925 | } | ||
| 926 | |||
| 927 | int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run) | ||
| 928 | { | ||
| 929 | const struct sys_reg_desc *target_specific; | ||
| 930 | size_t num; | ||
| 931 | |||
| 932 | target_specific = get_target_table(vcpu->arch.target, false, &num); | ||
| 933 | return kvm_handle_cp_32(vcpu, | ||
| 934 | cp15_regs, ARRAY_SIZE(cp15_regs), | ||
| 935 | target_specific, num); | ||
| 936 | } | ||
| 937 | |||
| 938 | int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run) | ||
| 939 | { | ||
| 940 | return kvm_handle_cp_64(vcpu, | ||
| 941 | cp14_64_regs, ARRAY_SIZE(cp14_64_regs), | ||
| 942 | NULL, 0); | ||
| 943 | } | ||
| 944 | |||
| 945 | int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run) | ||
| 946 | { | ||
| 947 | return kvm_handle_cp_32(vcpu, | ||
| 948 | cp14_regs, ARRAY_SIZE(cp14_regs), | ||
| 949 | NULL, 0); | ||
| 950 | } | ||
| 951 | |||
| 568 | static int emulate_sys_reg(struct kvm_vcpu *vcpu, | 952 | static int emulate_sys_reg(struct kvm_vcpu *vcpu, |
| 569 | const struct sys_reg_params *params) | 953 | const struct sys_reg_params *params) |
| 570 | { | 954 | { |
| @@ -776,17 +1160,15 @@ static struct sys_reg_desc invariant_sys_regs[] = { | |||
| 776 | NULL, get_ctr_el0 }, | 1160 | NULL, get_ctr_el0 }, |
| 777 | }; | 1161 | }; |
| 778 | 1162 | ||
| 779 | static int reg_from_user(void *val, const void __user *uaddr, u64 id) | 1163 | static int reg_from_user(u64 *val, const void __user *uaddr, u64 id) |
| 780 | { | 1164 | { |
| 781 | /* This Just Works because we are little endian. */ | ||
| 782 | if (copy_from_user(val, uaddr, KVM_REG_SIZE(id)) != 0) | 1165 | if (copy_from_user(val, uaddr, KVM_REG_SIZE(id)) != 0) |
| 783 | return -EFAULT; | 1166 | return -EFAULT; |
| 784 | return 0; | 1167 | return 0; |
| 785 | } | 1168 | } |
| 786 | 1169 | ||
| 787 | static int reg_to_user(void __user *uaddr, const void *val, u64 id) | 1170 | static int reg_to_user(void __user *uaddr, const u64 *val, u64 id) |
| 788 | { | 1171 | { |
| 789 | /* This Just Works because we are little endian. */ | ||
| 790 | if (copy_to_user(uaddr, val, KVM_REG_SIZE(id)) != 0) | 1172 | if (copy_to_user(uaddr, val, KVM_REG_SIZE(id)) != 0) |
| 791 | return -EFAULT; | 1173 | return -EFAULT; |
| 792 | return 0; | 1174 | return 0; |
| @@ -962,7 +1344,7 @@ static unsigned int num_demux_regs(void) | |||
| 962 | 1344 | ||
| 963 | static int write_demux_regids(u64 __user *uindices) | 1345 | static int write_demux_regids(u64 __user *uindices) |
| 964 | { | 1346 | { |
| 965 | u64 val = KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_DEMUX; | 1347 | u64 val = KVM_REG_ARM64 | KVM_REG_SIZE_U32 | KVM_REG_ARM_DEMUX; |
| 966 | unsigned int i; | 1348 | unsigned int i; |
| 967 | 1349 | ||
| 968 | val |= KVM_REG_ARM_DEMUX_ID_CCSIDR; | 1350 | val |= KVM_REG_ARM_DEMUX_ID_CCSIDR; |
| @@ -1069,14 +1451,32 @@ int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) | |||
| 1069 | return write_demux_regids(uindices); | 1451 | return write_demux_regids(uindices); |
| 1070 | } | 1452 | } |
| 1071 | 1453 | ||
| 1454 | static int check_sysreg_table(const struct sys_reg_desc *table, unsigned int n) | ||
| 1455 | { | ||
| 1456 | unsigned int i; | ||
| 1457 | |||
| 1458 | for (i = 1; i < n; i++) { | ||
| 1459 | if (cmp_sys_reg(&table[i-1], &table[i]) >= 0) { | ||
| 1460 | kvm_err("sys_reg table %p out of order (%d)\n", table, i - 1); | ||
| 1461 | return 1; | ||
| 1462 | } | ||
| 1463 | } | ||
| 1464 | |||
| 1465 | return 0; | ||
| 1466 | } | ||
| 1467 | |||
| 1072 | void kvm_sys_reg_table_init(void) | 1468 | void kvm_sys_reg_table_init(void) |
| 1073 | { | 1469 | { |
| 1074 | unsigned int i; | 1470 | unsigned int i; |
| 1075 | struct sys_reg_desc clidr; | 1471 | struct sys_reg_desc clidr; |
| 1076 | 1472 | ||
| 1077 | /* Make sure tables are unique and in order. */ | 1473 | /* Make sure tables are unique and in order. */ |
| 1078 | for (i = 1; i < ARRAY_SIZE(sys_reg_descs); i++) | 1474 | BUG_ON(check_sysreg_table(sys_reg_descs, ARRAY_SIZE(sys_reg_descs))); |
| 1079 | BUG_ON(cmp_sys_reg(&sys_reg_descs[i-1], &sys_reg_descs[i]) >= 0); | 1475 | BUG_ON(check_sysreg_table(cp14_regs, ARRAY_SIZE(cp14_regs))); |
| 1476 | BUG_ON(check_sysreg_table(cp14_64_regs, ARRAY_SIZE(cp14_64_regs))); | ||
| 1477 | BUG_ON(check_sysreg_table(cp15_regs, ARRAY_SIZE(cp15_regs))); | ||
| 1478 | BUG_ON(check_sysreg_table(cp15_64_regs, ARRAY_SIZE(cp15_64_regs))); | ||
| 1479 | BUG_ON(check_sysreg_table(invariant_sys_regs, ARRAY_SIZE(invariant_sys_regs))); | ||
| 1080 | 1480 | ||
| 1081 | /* We abuse the reset function to overwrite the table itself. */ | 1481 | /* We abuse the reset function to overwrite the table itself. */ |
| 1082 | for (i = 0; i < ARRAY_SIZE(invariant_sys_regs); i++) | 1482 | for (i = 0; i < ARRAY_SIZE(invariant_sys_regs); i++) |
diff --git a/arch/arm64/kvm/vgic-v2-switch.S b/arch/arm64/kvm/vgic-v2-switch.S new file mode 100644 index 000000000000..ae211772f991 --- /dev/null +++ b/arch/arm64/kvm/vgic-v2-switch.S | |||
| @@ -0,0 +1,133 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2012,2013 - ARM Ltd | ||
| 3 | * Author: Marc Zyngier <marc.zyngier@arm.com> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/linkage.h> | ||
| 19 | #include <linux/irqchip/arm-gic.h> | ||
| 20 | |||
| 21 | #include <asm/assembler.h> | ||
| 22 | #include <asm/memory.h> | ||
| 23 | #include <asm/asm-offsets.h> | ||
| 24 | #include <asm/kvm.h> | ||
| 25 | #include <asm/kvm_asm.h> | ||
| 26 | #include <asm/kvm_arm.h> | ||
| 27 | #include <asm/kvm_mmu.h> | ||
| 28 | |||
| 29 | .text | ||
| 30 | .pushsection .hyp.text, "ax" | ||
| 31 | |||
| 32 | /* | ||
| 33 | * Save the VGIC CPU state into memory | ||
| 34 | * x0: Register pointing to VCPU struct | ||
| 35 | * Do not corrupt x1!!! | ||
| 36 | */ | ||
| 37 | ENTRY(__save_vgic_v2_state) | ||
| 38 | __save_vgic_v2_state: | ||
| 39 | /* Get VGIC VCTRL base into x2 */ | ||
| 40 | ldr x2, [x0, #VCPU_KVM] | ||
| 41 | kern_hyp_va x2 | ||
| 42 | ldr x2, [x2, #KVM_VGIC_VCTRL] | ||
| 43 | kern_hyp_va x2 | ||
| 44 | cbz x2, 2f // disabled | ||
| 45 | |||
| 46 | /* Compute the address of struct vgic_cpu */ | ||
| 47 | add x3, x0, #VCPU_VGIC_CPU | ||
| 48 | |||
| 49 | /* Save all interesting registers */ | ||
| 50 | ldr w4, [x2, #GICH_HCR] | ||
| 51 | ldr w5, [x2, #GICH_VMCR] | ||
| 52 | ldr w6, [x2, #GICH_MISR] | ||
| 53 | ldr w7, [x2, #GICH_EISR0] | ||
| 54 | ldr w8, [x2, #GICH_EISR1] | ||
| 55 | ldr w9, [x2, #GICH_ELRSR0] | ||
| 56 | ldr w10, [x2, #GICH_ELRSR1] | ||
| 57 | ldr w11, [x2, #GICH_APR] | ||
| 58 | CPU_BE( rev w4, w4 ) | ||
| 59 | CPU_BE( rev w5, w5 ) | ||
| 60 | CPU_BE( rev w6, w6 ) | ||
| 61 | CPU_BE( rev w7, w7 ) | ||
| 62 | CPU_BE( rev w8, w8 ) | ||
| 63 | CPU_BE( rev w9, w9 ) | ||
| 64 | CPU_BE( rev w10, w10 ) | ||
| 65 | CPU_BE( rev w11, w11 ) | ||
| 66 | |||
| 67 | str w4, [x3, #VGIC_V2_CPU_HCR] | ||
| 68 | str w5, [x3, #VGIC_V2_CPU_VMCR] | ||
| 69 | str w6, [x3, #VGIC_V2_CPU_MISR] | ||
| 70 | str w7, [x3, #VGIC_V2_CPU_EISR] | ||
| 71 | str w8, [x3, #(VGIC_V2_CPU_EISR + 4)] | ||
| 72 | str w9, [x3, #VGIC_V2_CPU_ELRSR] | ||
| 73 | str w10, [x3, #(VGIC_V2_CPU_ELRSR + 4)] | ||
| 74 | str w11, [x3, #VGIC_V2_CPU_APR] | ||
| 75 | |||
| 76 | /* Clear GICH_HCR */ | ||
| 77 | str wzr, [x2, #GICH_HCR] | ||
| 78 | |||
| 79 | /* Save list registers */ | ||
| 80 | add x2, x2, #GICH_LR0 | ||
| 81 | ldr w4, [x3, #VGIC_CPU_NR_LR] | ||
| 82 | add x3, x3, #VGIC_V2_CPU_LR | ||
| 83 | 1: ldr w5, [x2], #4 | ||
| 84 | CPU_BE( rev w5, w5 ) | ||
| 85 | str w5, [x3], #4 | ||
| 86 | sub w4, w4, #1 | ||
| 87 | cbnz w4, 1b | ||
| 88 | 2: | ||
| 89 | ret | ||
| 90 | ENDPROC(__save_vgic_v2_state) | ||
| 91 | |||
| 92 | /* | ||
| 93 | * Restore the VGIC CPU state from memory | ||
| 94 | * x0: Register pointing to VCPU struct | ||
| 95 | */ | ||
| 96 | ENTRY(__restore_vgic_v2_state) | ||
| 97 | __restore_vgic_v2_state: | ||
| 98 | /* Get VGIC VCTRL base into x2 */ | ||
| 99 | ldr x2, [x0, #VCPU_KVM] | ||
| 100 | kern_hyp_va x2 | ||
| 101 | ldr x2, [x2, #KVM_VGIC_VCTRL] | ||
| 102 | kern_hyp_va x2 | ||
| 103 | cbz x2, 2f // disabled | ||
| 104 | |||
| 105 | /* Compute the address of struct vgic_cpu */ | ||
| 106 | add x3, x0, #VCPU_VGIC_CPU | ||
| 107 | |||
| 108 | /* We only restore a minimal set of registers */ | ||
| 109 | ldr w4, [x3, #VGIC_V2_CPU_HCR] | ||
| 110 | ldr w5, [x3, #VGIC_V2_CPU_VMCR] | ||
| 111 | ldr w6, [x3, #VGIC_V2_CPU_APR] | ||
| 112 | CPU_BE( rev w4, w4 ) | ||
| 113 | CPU_BE( rev w5, w5 ) | ||
| 114 | CPU_BE( rev w6, w6 ) | ||
| 115 | |||
| 116 | str w4, [x2, #GICH_HCR] | ||
| 117 | str w5, [x2, #GICH_VMCR] | ||
| 118 | str w6, [x2, #GICH_APR] | ||
| 119 | |||
| 120 | /* Restore list registers */ | ||
| 121 | add x2, x2, #GICH_LR0 | ||
| 122 | ldr w4, [x3, #VGIC_CPU_NR_LR] | ||
| 123 | add x3, x3, #VGIC_V2_CPU_LR | ||
| 124 | 1: ldr w5, [x3], #4 | ||
| 125 | CPU_BE( rev w5, w5 ) | ||
| 126 | str w5, [x2], #4 | ||
| 127 | sub w4, w4, #1 | ||
| 128 | cbnz w4, 1b | ||
| 129 | 2: | ||
| 130 | ret | ||
| 131 | ENDPROC(__restore_vgic_v2_state) | ||
| 132 | |||
| 133 | .popsection | ||
diff --git a/arch/arm64/kvm/vgic-v3-switch.S b/arch/arm64/kvm/vgic-v3-switch.S new file mode 100644 index 000000000000..d16046999e06 --- /dev/null +++ b/arch/arm64/kvm/vgic-v3-switch.S | |||
| @@ -0,0 +1,267 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2012,2013 - ARM Ltd | ||
| 3 | * Author: Marc Zyngier <marc.zyngier@arm.com> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/linkage.h> | ||
| 19 | #include <linux/irqchip/arm-gic-v3.h> | ||
| 20 | |||
| 21 | #include <asm/assembler.h> | ||
| 22 | #include <asm/memory.h> | ||
| 23 | #include <asm/asm-offsets.h> | ||
| 24 | #include <asm/kvm.h> | ||
| 25 | #include <asm/kvm_asm.h> | ||
| 26 | #include <asm/kvm_arm.h> | ||
| 27 | |||
| 28 | .text | ||
| 29 | .pushsection .hyp.text, "ax" | ||
| 30 | |||
| 31 | /* | ||
| 32 | * We store LRs in reverse order to let the CPU deal with streaming | ||
| 33 | * access. Use this macro to make it look saner... | ||
| 34 | */ | ||
| 35 | #define LR_OFFSET(n) (VGIC_V3_CPU_LR + (15 - n) * 8) | ||
| 36 | |||
| 37 | /* | ||
| 38 | * Save the VGIC CPU state into memory | ||
| 39 | * x0: Register pointing to VCPU struct | ||
| 40 | * Do not corrupt x1!!! | ||
| 41 | */ | ||
| 42 | .macro save_vgic_v3_state | ||
| 43 | // Compute the address of struct vgic_cpu | ||
| 44 | add x3, x0, #VCPU_VGIC_CPU | ||
| 45 | |||
| 46 | // Make sure stores to the GIC via the memory mapped interface | ||
| 47 | // are now visible to the system register interface | ||
| 48 | dsb st | ||
| 49 | |||
| 50 | // Save all interesting registers | ||
| 51 | mrs_s x4, ICH_HCR_EL2 | ||
| 52 | mrs_s x5, ICH_VMCR_EL2 | ||
| 53 | mrs_s x6, ICH_MISR_EL2 | ||
| 54 | mrs_s x7, ICH_EISR_EL2 | ||
| 55 | mrs_s x8, ICH_ELSR_EL2 | ||
| 56 | |||
| 57 | str w4, [x3, #VGIC_V3_CPU_HCR] | ||
| 58 | str w5, [x3, #VGIC_V3_CPU_VMCR] | ||
| 59 | str w6, [x3, #VGIC_V3_CPU_MISR] | ||
| 60 | str w7, [x3, #VGIC_V3_CPU_EISR] | ||
| 61 | str w8, [x3, #VGIC_V3_CPU_ELRSR] | ||
| 62 | |||
| 63 | msr_s ICH_HCR_EL2, xzr | ||
| 64 | |||
| 65 | mrs_s x21, ICH_VTR_EL2 | ||
| 66 | mvn w22, w21 | ||
| 67 | ubfiz w23, w22, 2, 4 // w23 = (15 - ListRegs) * 4 | ||
| 68 | |||
| 69 | adr x24, 1f | ||
| 70 | add x24, x24, x23 | ||
| 71 | br x24 | ||
| 72 | |||
| 73 | 1: | ||
| 74 | mrs_s x20, ICH_LR15_EL2 | ||
| 75 | mrs_s x19, ICH_LR14_EL2 | ||
| 76 | mrs_s x18, ICH_LR13_EL2 | ||
| 77 | mrs_s x17, ICH_LR12_EL2 | ||
| 78 | mrs_s x16, ICH_LR11_EL2 | ||
| 79 | mrs_s x15, ICH_LR10_EL2 | ||
| 80 | mrs_s x14, ICH_LR9_EL2 | ||
| 81 | mrs_s x13, ICH_LR8_EL2 | ||
| 82 | mrs_s x12, ICH_LR7_EL2 | ||
| 83 | mrs_s x11, ICH_LR6_EL2 | ||
| 84 | mrs_s x10, ICH_LR5_EL2 | ||
| 85 | mrs_s x9, ICH_LR4_EL2 | ||
| 86 | mrs_s x8, ICH_LR3_EL2 | ||
| 87 | mrs_s x7, ICH_LR2_EL2 | ||
| 88 | mrs_s x6, ICH_LR1_EL2 | ||
| 89 | mrs_s x5, ICH_LR0_EL2 | ||
| 90 | |||
| 91 | adr x24, 1f | ||
| 92 | add x24, x24, x23 | ||
| 93 | br x24 | ||
| 94 | |||
| 95 | 1: | ||
| 96 | str x20, [x3, #LR_OFFSET(15)] | ||
| 97 | str x19, [x3, #LR_OFFSET(14)] | ||
| 98 | str x18, [x3, #LR_OFFSET(13)] | ||
| 99 | str x17, [x3, #LR_OFFSET(12)] | ||
| 100 | str x16, [x3, #LR_OFFSET(11)] | ||
| 101 | str x15, [x3, #LR_OFFSET(10)] | ||
| 102 | str x14, [x3, #LR_OFFSET(9)] | ||
| 103 | str x13, [x3, #LR_OFFSET(8)] | ||
| 104 | str x12, [x3, #LR_OFFSET(7)] | ||
| 105 | str x11, [x3, #LR_OFFSET(6)] | ||
| 106 | str x10, [x3, #LR_OFFSET(5)] | ||
| 107 | str x9, [x3, #LR_OFFSET(4)] | ||
| 108 | str x8, [x3, #LR_OFFSET(3)] | ||
| 109 | str x7, [x3, #LR_OFFSET(2)] | ||
| 110 | str x6, [x3, #LR_OFFSET(1)] | ||
| 111 | str x5, [x3, #LR_OFFSET(0)] | ||
| 112 | |||
| 113 | tbnz w21, #29, 6f // 6 bits | ||
| 114 | tbz w21, #30, 5f // 5 bits | ||
| 115 | // 7 bits | ||
| 116 | mrs_s x20, ICH_AP0R3_EL2 | ||
| 117 | str w20, [x3, #(VGIC_V3_CPU_AP0R + 3*4)] | ||
| 118 | mrs_s x19, ICH_AP0R2_EL2 | ||
| 119 | str w19, [x3, #(VGIC_V3_CPU_AP0R + 2*4)] | ||
| 120 | 6: mrs_s x18, ICH_AP0R1_EL2 | ||
| 121 | str w18, [x3, #(VGIC_V3_CPU_AP0R + 1*4)] | ||
| 122 | 5: mrs_s x17, ICH_AP0R0_EL2 | ||
| 123 | str w17, [x3, #VGIC_V3_CPU_AP0R] | ||
| 124 | |||
| 125 | tbnz w21, #29, 6f // 6 bits | ||
| 126 | tbz w21, #30, 5f // 5 bits | ||
| 127 | // 7 bits | ||
| 128 | mrs_s x20, ICH_AP1R3_EL2 | ||
| 129 | str w20, [x3, #(VGIC_V3_CPU_AP1R + 3*4)] | ||
| 130 | mrs_s x19, ICH_AP1R2_EL2 | ||
| 131 | str w19, [x3, #(VGIC_V3_CPU_AP1R + 2*4)] | ||
| 132 | 6: mrs_s x18, ICH_AP1R1_EL2 | ||
| 133 | str w18, [x3, #(VGIC_V3_CPU_AP1R + 1*4)] | ||
| 134 | 5: mrs_s x17, ICH_AP1R0_EL2 | ||
| 135 | str w17, [x3, #VGIC_V3_CPU_AP1R] | ||
| 136 | |||
| 137 | // Restore SRE_EL1 access and re-enable SRE at EL1. | ||
| 138 | mrs_s x5, ICC_SRE_EL2 | ||
| 139 | orr x5, x5, #ICC_SRE_EL2_ENABLE | ||
| 140 | msr_s ICC_SRE_EL2, x5 | ||
| 141 | isb | ||
| 142 | mov x5, #1 | ||
| 143 | msr_s ICC_SRE_EL1, x5 | ||
| 144 | .endm | ||
| 145 | |||
| 146 | /* | ||
| 147 | * Restore the VGIC CPU state from memory | ||
| 148 | * x0: Register pointing to VCPU struct | ||
| 149 | */ | ||
| 150 | .macro restore_vgic_v3_state | ||
| 151 | // Disable SRE_EL1 access. Necessary, otherwise | ||
| 152 | // ICH_VMCR_EL2.VFIQEn becomes one, and FIQ happens... | ||
| 153 | msr_s ICC_SRE_EL1, xzr | ||
| 154 | isb | ||
| 155 | |||
| 156 | // Compute the address of struct vgic_cpu | ||
| 157 | add x3, x0, #VCPU_VGIC_CPU | ||
| 158 | |||
| 159 | // Restore all interesting registers | ||
| 160 | ldr w4, [x3, #VGIC_V3_CPU_HCR] | ||
| 161 | ldr w5, [x3, #VGIC_V3_CPU_VMCR] | ||
| 162 | |||
| 163 | msr_s ICH_HCR_EL2, x4 | ||
| 164 | msr_s ICH_VMCR_EL2, x5 | ||
| 165 | |||
| 166 | mrs_s x21, ICH_VTR_EL2 | ||
| 167 | |||
| 168 | tbnz w21, #29, 6f // 6 bits | ||
| 169 | tbz w21, #30, 5f // 5 bits | ||
| 170 | // 7 bits | ||
| 171 | ldr w20, [x3, #(VGIC_V3_CPU_AP1R + 3*4)] | ||
| 172 | msr_s ICH_AP1R3_EL2, x20 | ||
| 173 | ldr w19, [x3, #(VGIC_V3_CPU_AP1R + 2*4)] | ||
| 174 | msr_s ICH_AP1R2_EL2, x19 | ||
| 175 | 6: ldr w18, [x3, #(VGIC_V3_CPU_AP1R + 1*4)] | ||
| 176 | msr_s ICH_AP1R1_EL2, x18 | ||
| 177 | 5: ldr w17, [x3, #VGIC_V3_CPU_AP1R] | ||
| 178 | msr_s ICH_AP1R0_EL2, x17 | ||
| 179 | |||
| 180 | tbnz w21, #29, 6f // 6 bits | ||
| 181 | tbz w21, #30, 5f // 5 bits | ||
| 182 | // 7 bits | ||
| 183 | ldr w20, [x3, #(VGIC_V3_CPU_AP0R + 3*4)] | ||
| 184 | msr_s ICH_AP0R3_EL2, x20 | ||
| 185 | ldr w19, [x3, #(VGIC_V3_CPU_AP0R + 2*4)] | ||
| 186 | msr_s ICH_AP0R2_EL2, x19 | ||
| 187 | 6: ldr w18, [x3, #(VGIC_V3_CPU_AP0R + 1*4)] | ||
| 188 | msr_s ICH_AP0R1_EL2, x18 | ||
| 189 | 5: ldr w17, [x3, #VGIC_V3_CPU_AP0R] | ||
| 190 | msr_s ICH_AP0R0_EL2, x17 | ||
| 191 | |||
| 192 | and w22, w21, #0xf | ||
| 193 | mvn w22, w21 | ||
| 194 | ubfiz w23, w22, 2, 4 // w23 = (15 - ListRegs) * 4 | ||
| 195 | |||
| 196 | adr x24, 1f | ||
| 197 | add x24, x24, x23 | ||
| 198 | br x24 | ||
| 199 | |||
| 200 | 1: | ||
| 201 | ldr x20, [x3, #LR_OFFSET(15)] | ||
| 202 | ldr x19, [x3, #LR_OFFSET(14)] | ||
| 203 | ldr x18, [x3, #LR_OFFSET(13)] | ||
| 204 | ldr x17, [x3, #LR_OFFSET(12)] | ||
| 205 | ldr x16, [x3, #LR_OFFSET(11)] | ||
| 206 | ldr x15, [x3, #LR_OFFSET(10)] | ||
| 207 | ldr x14, [x3, #LR_OFFSET(9)] | ||
| 208 | ldr x13, [x3, #LR_OFFSET(8)] | ||
| 209 | ldr x12, [x3, #LR_OFFSET(7)] | ||
| 210 | ldr x11, [x3, #LR_OFFSET(6)] | ||
| 211 | ldr x10, [x3, #LR_OFFSET(5)] | ||
| 212 | ldr x9, [x3, #LR_OFFSET(4)] | ||
| 213 | ldr x8, [x3, #LR_OFFSET(3)] | ||
| 214 | ldr x7, [x3, #LR_OFFSET(2)] | ||
| 215 | ldr x6, [x3, #LR_OFFSET(1)] | ||
| 216 | ldr x5, [x3, #LR_OFFSET(0)] | ||
| 217 | |||
| 218 | adr x24, 1f | ||
| 219 | add x24, x24, x23 | ||
| 220 | br x24 | ||
| 221 | |||
| 222 | 1: | ||
| 223 | msr_s ICH_LR15_EL2, x20 | ||
| 224 | msr_s ICH_LR14_EL2, x19 | ||
| 225 | msr_s ICH_LR13_EL2, x18 | ||
| 226 | msr_s ICH_LR12_EL2, x17 | ||
| 227 | msr_s ICH_LR11_EL2, x16 | ||
| 228 | msr_s ICH_LR10_EL2, x15 | ||
| 229 | msr_s ICH_LR9_EL2, x14 | ||
| 230 | msr_s ICH_LR8_EL2, x13 | ||
| 231 | msr_s ICH_LR7_EL2, x12 | ||
| 232 | msr_s ICH_LR6_EL2, x11 | ||
| 233 | msr_s ICH_LR5_EL2, x10 | ||
| 234 | msr_s ICH_LR4_EL2, x9 | ||
| 235 | msr_s ICH_LR3_EL2, x8 | ||
| 236 | msr_s ICH_LR2_EL2, x7 | ||
| 237 | msr_s ICH_LR1_EL2, x6 | ||
| 238 | msr_s ICH_LR0_EL2, x5 | ||
| 239 | |||
| 240 | // Ensure that the above will have reached the | ||
| 241 | // (re)distributors. This ensure the guest will read | ||
| 242 | // the correct values from the memory-mapped interface. | ||
| 243 | isb | ||
| 244 | dsb sy | ||
| 245 | |||
| 246 | // Prevent the guest from touching the GIC system registers | ||
| 247 | mrs_s x5, ICC_SRE_EL2 | ||
| 248 | and x5, x5, #~ICC_SRE_EL2_ENABLE | ||
| 249 | msr_s ICC_SRE_EL2, x5 | ||
| 250 | .endm | ||
| 251 | |||
| 252 | ENTRY(__save_vgic_v3_state) | ||
| 253 | save_vgic_v3_state | ||
| 254 | ret | ||
| 255 | ENDPROC(__save_vgic_v3_state) | ||
| 256 | |||
| 257 | ENTRY(__restore_vgic_v3_state) | ||
| 258 | restore_vgic_v3_state | ||
| 259 | ret | ||
| 260 | ENDPROC(__restore_vgic_v3_state) | ||
| 261 | |||
| 262 | ENTRY(__vgic_v3_get_ich_vtr_el2) | ||
| 263 | mrs_s x0, ICH_VTR_EL2 | ||
| 264 | ret | ||
| 265 | ENDPROC(__vgic_v3_get_ich_vtr_el2) | ||
| 266 | |||
| 267 | .popsection | ||
diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig index 990b86420cc6..3d50ea955c4c 100644 --- a/arch/ia64/kvm/Kconfig +++ b/arch/ia64/kvm/Kconfig | |||
| @@ -25,6 +25,7 @@ config KVM | |||
| 25 | select PREEMPT_NOTIFIERS | 25 | select PREEMPT_NOTIFIERS |
| 26 | select ANON_INODES | 26 | select ANON_INODES |
| 27 | select HAVE_KVM_IRQCHIP | 27 | select HAVE_KVM_IRQCHIP |
| 28 | select HAVE_KVM_IRQFD | ||
| 28 | select HAVE_KVM_IRQ_ROUTING | 29 | select HAVE_KVM_IRQ_ROUTING |
| 29 | select KVM_APIC_ARCHITECTURE | 30 | select KVM_APIC_ARCHITECTURE |
| 30 | select KVM_MMIO | 31 | select KVM_MMIO |
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 6a4309bb821a..0729ba6acddf 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
| @@ -190,7 +190,7 @@ void kvm_arch_check_processor_compat(void *rtn) | |||
| 190 | *(int *)rtn = 0; | 190 | *(int *)rtn = 0; |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | int kvm_dev_ioctl_check_extension(long ext) | 193 | int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) |
| 194 | { | 194 | { |
| 195 | 195 | ||
| 196 | int r; | 196 | int r; |
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c index 4fda672cb58e..cd7114147ae7 100644 --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c | |||
| @@ -886,7 +886,7 @@ int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf) | |||
| 886 | return VM_FAULT_SIGBUS; | 886 | return VM_FAULT_SIGBUS; |
| 887 | } | 887 | } |
| 888 | 888 | ||
| 889 | int kvm_dev_ioctl_check_extension(long ext) | 889 | int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) |
| 890 | { | 890 | { |
| 891 | int r; | 891 | int r; |
| 892 | 892 | ||
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index 35d16bd2760b..ec2e40f2cc11 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug | |||
| @@ -202,9 +202,7 @@ config PPC_EARLY_DEBUG_BEAT | |||
| 202 | 202 | ||
| 203 | config PPC_EARLY_DEBUG_44x | 203 | config PPC_EARLY_DEBUG_44x |
| 204 | bool "Early serial debugging for IBM/AMCC 44x CPUs" | 204 | bool "Early serial debugging for IBM/AMCC 44x CPUs" |
| 205 | # PPC_EARLY_DEBUG on 440 leaves AS=1 mappings above the TLB high water | 205 | depends on 44x |
| 206 | # mark, which doesn't work with current 440 KVM. | ||
| 207 | depends on 44x && !KVM | ||
| 208 | help | 206 | help |
| 209 | Select this to enable early debugging for IBM 44x chips via the | 207 | Select this to enable early debugging for IBM 44x chips via the |
| 210 | inbuilt serial port. If you enable this, ensure you set | 208 | inbuilt serial port. If you enable this, ensure you set |
diff --git a/arch/powerpc/configs/ppc44x_defconfig b/arch/powerpc/configs/ppc44x_defconfig index ccf66b9060a6..924e10df1844 100644 --- a/arch/powerpc/configs/ppc44x_defconfig +++ b/arch/powerpc/configs/ppc44x_defconfig | |||
| @@ -127,4 +127,3 @@ CONFIG_CRYPTO_PCBC=y | |||
| 127 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 127 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 128 | # CONFIG_CRYPTO_HW is not set | 128 | # CONFIG_CRYPTO_HW is not set |
| 129 | CONFIG_VIRTUALIZATION=y | 129 | CONFIG_VIRTUALIZATION=y |
| 130 | CONFIG_KVM_440=y | ||
diff --git a/arch/powerpc/include/asm/asm-compat.h b/arch/powerpc/include/asm/asm-compat.h index 4b237aa35660..21be8ae8f809 100644 --- a/arch/powerpc/include/asm/asm-compat.h +++ b/arch/powerpc/include/asm/asm-compat.h | |||
| @@ -34,10 +34,14 @@ | |||
| 34 | #define PPC_MIN_STKFRM 112 | 34 | #define PPC_MIN_STKFRM 112 |
| 35 | 35 | ||
| 36 | #ifdef __BIG_ENDIAN__ | 36 | #ifdef __BIG_ENDIAN__ |
| 37 | #define LWZX_BE stringify_in_c(lwzx) | ||
| 37 | #define LDX_BE stringify_in_c(ldx) | 38 | #define LDX_BE stringify_in_c(ldx) |
| 39 | #define STWX_BE stringify_in_c(stwx) | ||
| 38 | #define STDX_BE stringify_in_c(stdx) | 40 | #define STDX_BE stringify_in_c(stdx) |
| 39 | #else | 41 | #else |
| 42 | #define LWZX_BE stringify_in_c(lwbrx) | ||
| 40 | #define LDX_BE stringify_in_c(ldbrx) | 43 | #define LDX_BE stringify_in_c(ldbrx) |
| 44 | #define STWX_BE stringify_in_c(stwbrx) | ||
| 41 | #define STDX_BE stringify_in_c(stdbrx) | 45 | #define STDX_BE stringify_in_c(stdbrx) |
| 42 | #endif | 46 | #endif |
| 43 | 47 | ||
diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h index ed0afc1e44a4..34a05a1a990b 100644 --- a/arch/powerpc/include/asm/cache.h +++ b/arch/powerpc/include/asm/cache.h | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #ifdef __KERNEL__ | 4 | #ifdef __KERNEL__ |
| 5 | 5 | ||
| 6 | #include <asm/reg.h> | ||
| 6 | 7 | ||
| 7 | /* bytes per L1 cache line */ | 8 | /* bytes per L1 cache line */ |
| 8 | #if defined(CONFIG_8xx) || defined(CONFIG_403GCX) | 9 | #if defined(CONFIG_8xx) || defined(CONFIG_403GCX) |
| @@ -39,6 +40,12 @@ struct ppc64_caches { | |||
| 39 | }; | 40 | }; |
| 40 | 41 | ||
| 41 | extern struct ppc64_caches ppc64_caches; | 42 | extern struct ppc64_caches ppc64_caches; |
| 43 | |||
| 44 | static inline void logmpp(u64 x) | ||
| 45 | { | ||
| 46 | asm volatile(PPC_LOGMPP(R1) : : "r" (x)); | ||
| 47 | } | ||
| 48 | |||
| 42 | #endif /* __powerpc64__ && ! __ASSEMBLY__ */ | 49 | #endif /* __powerpc64__ && ! __ASSEMBLY__ */ |
| 43 | 50 | ||
| 44 | #if defined(__ASSEMBLY__) | 51 | #if defined(__ASSEMBLY__) |
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index 5dbbb29f5c3e..85bc8c0d257b 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h | |||
| @@ -279,6 +279,12 @@ | |||
| 279 | #define H_GET_24X7_DATA 0xF07C | 279 | #define H_GET_24X7_DATA 0xF07C |
| 280 | #define H_GET_PERF_COUNTER_INFO 0xF080 | 280 | #define H_GET_PERF_COUNTER_INFO 0xF080 |
| 281 | 281 | ||
| 282 | /* Values for 2nd argument to H_SET_MODE */ | ||
| 283 | #define H_SET_MODE_RESOURCE_SET_CIABR 1 | ||
| 284 | #define H_SET_MODE_RESOURCE_SET_DAWR 2 | ||
| 285 | #define H_SET_MODE_RESOURCE_ADDR_TRANS_MODE 3 | ||
| 286 | #define H_SET_MODE_RESOURCE_LE 4 | ||
| 287 | |||
| 282 | #ifndef __ASSEMBLY__ | 288 | #ifndef __ASSEMBLY__ |
| 283 | 289 | ||
| 284 | /** | 290 | /** |
diff --git a/arch/powerpc/include/asm/kvm_44x.h b/arch/powerpc/include/asm/kvm_44x.h deleted file mode 100644 index a0e57618ff33..000000000000 --- a/arch/powerpc/include/asm/kvm_44x.h +++ /dev/null | |||
| @@ -1,67 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify | ||
| 3 | * it under the terms of the GNU General Public License, version 2, as | ||
| 4 | * published by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * This program is distributed in the hope that it will be useful, | ||
| 7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 9 | * GNU General Public License for more details. | ||
| 10 | * | ||
| 11 | * You should have received a copy of the GNU General Public License | ||
| 12 | * along with this program; if not, write to the Free Software | ||
| 13 | * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 14 | * | ||
| 15 | * Copyright IBM Corp. 2008 | ||
| 16 | * | ||
| 17 | * Authors: Hollis Blanchard <hollisb@us.ibm.com> | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef __ASM_44X_H__ | ||
| 21 | #define __ASM_44X_H__ | ||
| 22 | |||
| 23 | #include <linux/kvm_host.h> | ||
| 24 | |||
| 25 | #define PPC44x_TLB_SIZE 64 | ||
| 26 | |||
| 27 | /* If the guest is expecting it, this can be as large as we like; we'd just | ||
| 28 | * need to find some way of advertising it. */ | ||
| 29 | #define KVM44x_GUEST_TLB_SIZE 64 | ||
| 30 | |||
| 31 | struct kvmppc_44x_tlbe { | ||
| 32 | u32 tid; /* Only the low 8 bits are used. */ | ||
| 33 | u32 word0; | ||
| 34 | u32 word1; | ||
| 35 | u32 word2; | ||
| 36 | }; | ||
| 37 | |||
| 38 | struct kvmppc_44x_shadow_ref { | ||
| 39 | struct page *page; | ||
| 40 | u16 gtlb_index; | ||
| 41 | u8 writeable; | ||
| 42 | u8 tid; | ||
| 43 | }; | ||
| 44 | |||
| 45 | struct kvmppc_vcpu_44x { | ||
| 46 | /* Unmodified copy of the guest's TLB. */ | ||
| 47 | struct kvmppc_44x_tlbe guest_tlb[KVM44x_GUEST_TLB_SIZE]; | ||
| 48 | |||
| 49 | /* References to guest pages in the hardware TLB. */ | ||
| 50 | struct kvmppc_44x_shadow_ref shadow_refs[PPC44x_TLB_SIZE]; | ||
| 51 | |||
| 52 | /* State of the shadow TLB at guest context switch time. */ | ||
| 53 | struct kvmppc_44x_tlbe shadow_tlb[PPC44x_TLB_SIZE]; | ||
| 54 | u8 shadow_tlb_mod[PPC44x_TLB_SIZE]; | ||
| 55 | |||
| 56 | struct kvm_vcpu vcpu; | ||
| 57 | }; | ||
| 58 | |||
| 59 | static inline struct kvmppc_vcpu_44x *to_44x(struct kvm_vcpu *vcpu) | ||
| 60 | { | ||
| 61 | return container_of(vcpu, struct kvmppc_vcpu_44x, vcpu); | ||
| 62 | } | ||
| 63 | |||
| 64 | void kvmppc_44x_tlb_put(struct kvm_vcpu *vcpu); | ||
| 65 | void kvmppc_44x_tlb_load(struct kvm_vcpu *vcpu); | ||
| 66 | |||
| 67 | #endif /* __ASM_44X_H__ */ | ||
diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h index ecf7e133a4f2..465dfcb82c92 100644 --- a/arch/powerpc/include/asm/kvm_asm.h +++ b/arch/powerpc/include/asm/kvm_asm.h | |||
| @@ -33,7 +33,6 @@ | |||
| 33 | /* IVPR must be 64KiB-aligned. */ | 33 | /* IVPR must be 64KiB-aligned. */ |
| 34 | #define VCPU_SIZE_ORDER 4 | 34 | #define VCPU_SIZE_ORDER 4 |
| 35 | #define VCPU_SIZE_LOG (VCPU_SIZE_ORDER + 12) | 35 | #define VCPU_SIZE_LOG (VCPU_SIZE_ORDER + 12) |
| 36 | #define VCPU_TLB_PGSZ PPC44x_TLB_64K | ||
| 37 | #define VCPU_SIZE_BYTES (1<<VCPU_SIZE_LOG) | 36 | #define VCPU_SIZE_BYTES (1<<VCPU_SIZE_LOG) |
| 38 | 37 | ||
| 39 | #define BOOKE_INTERRUPT_CRITICAL 0 | 38 | #define BOOKE_INTERRUPT_CRITICAL 0 |
| @@ -132,6 +131,7 @@ | |||
| 132 | #define BOOK3S_HFLAG_NATIVE_PS 0x8 | 131 | #define BOOK3S_HFLAG_NATIVE_PS 0x8 |
| 133 | #define BOOK3S_HFLAG_MULTI_PGSIZE 0x10 | 132 | #define BOOK3S_HFLAG_MULTI_PGSIZE 0x10 |
| 134 | #define BOOK3S_HFLAG_NEW_TLBIE 0x20 | 133 | #define BOOK3S_HFLAG_NEW_TLBIE 0x20 |
| 134 | #define BOOK3S_HFLAG_SPLIT_HACK 0x40 | ||
| 135 | 135 | ||
| 136 | #define RESUME_FLAG_NV (1<<0) /* Reload guest nonvolatile state? */ | 136 | #define RESUME_FLAG_NV (1<<0) /* Reload guest nonvolatile state? */ |
| 137 | #define RESUME_FLAG_HOST (1<<1) /* Resume host? */ | 137 | #define RESUME_FLAG_HOST (1<<1) /* Resume host? */ |
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index f52f65694527..6acf0c2a0f99 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h | |||
| @@ -83,8 +83,6 @@ struct kvmppc_vcpu_book3s { | |||
| 83 | u64 sdr1; | 83 | u64 sdr1; |
| 84 | u64 hior; | 84 | u64 hior; |
| 85 | u64 msr_mask; | 85 | u64 msr_mask; |
| 86 | u64 purr_offset; | ||
| 87 | u64 spurr_offset; | ||
| 88 | #ifdef CONFIG_PPC_BOOK3S_32 | 86 | #ifdef CONFIG_PPC_BOOK3S_32 |
| 89 | u32 vsid_pool[VSID_POOL_SIZE]; | 87 | u32 vsid_pool[VSID_POOL_SIZE]; |
| 90 | u32 vsid_next; | 88 | u32 vsid_next; |
| @@ -148,9 +146,10 @@ extern void kvmppc_mmu_invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache * | |||
| 148 | extern int kvmppc_mmu_hpte_sysinit(void); | 146 | extern int kvmppc_mmu_hpte_sysinit(void); |
| 149 | extern void kvmppc_mmu_hpte_sysexit(void); | 147 | extern void kvmppc_mmu_hpte_sysexit(void); |
| 150 | extern int kvmppc_mmu_hv_init(void); | 148 | extern int kvmppc_mmu_hv_init(void); |
| 149 | extern int kvmppc_book3s_hcall_implemented(struct kvm *kvm, unsigned long hc); | ||
| 151 | 150 | ||
| 151 | /* XXX remove this export when load_last_inst() is generic */ | ||
| 152 | extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data); | 152 | extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data); |
| 153 | extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data); | ||
| 154 | extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec); | 153 | extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec); |
| 155 | extern void kvmppc_book3s_dequeue_irqprio(struct kvm_vcpu *vcpu, | 154 | extern void kvmppc_book3s_dequeue_irqprio(struct kvm_vcpu *vcpu, |
| 156 | unsigned int vec); | 155 | unsigned int vec); |
| @@ -159,13 +158,13 @@ extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, | |||
| 159 | bool upper, u32 val); | 158 | bool upper, u32 val); |
| 160 | extern void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr); | 159 | extern void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr); |
| 161 | extern int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu); | 160 | extern int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu); |
| 162 | extern pfn_t kvmppc_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn, bool writing, | 161 | extern pfn_t kvmppc_gpa_to_pfn(struct kvm_vcpu *vcpu, gpa_t gpa, bool writing, |
| 163 | bool *writable); | 162 | bool *writable); |
| 164 | extern void kvmppc_add_revmap_chain(struct kvm *kvm, struct revmap_entry *rev, | 163 | extern void kvmppc_add_revmap_chain(struct kvm *kvm, struct revmap_entry *rev, |
| 165 | unsigned long *rmap, long pte_index, int realmode); | 164 | unsigned long *rmap, long pte_index, int realmode); |
| 166 | extern void kvmppc_invalidate_hpte(struct kvm *kvm, unsigned long *hptep, | 165 | extern void kvmppc_invalidate_hpte(struct kvm *kvm, __be64 *hptep, |
| 167 | unsigned long pte_index); | 166 | unsigned long pte_index); |
| 168 | void kvmppc_clear_ref_hpte(struct kvm *kvm, unsigned long *hptep, | 167 | void kvmppc_clear_ref_hpte(struct kvm *kvm, __be64 *hptep, |
| 169 | unsigned long pte_index); | 168 | unsigned long pte_index); |
| 170 | extern void *kvmppc_pin_guest_page(struct kvm *kvm, unsigned long addr, | 169 | extern void *kvmppc_pin_guest_page(struct kvm *kvm, unsigned long addr, |
| 171 | unsigned long *nb_ret); | 170 | unsigned long *nb_ret); |
| @@ -183,12 +182,16 @@ extern long kvmppc_hv_get_dirty_log(struct kvm *kvm, | |||
| 183 | struct kvm_memory_slot *memslot, unsigned long *map); | 182 | struct kvm_memory_slot *memslot, unsigned long *map); |
| 184 | extern void kvmppc_update_lpcr(struct kvm *kvm, unsigned long lpcr, | 183 | extern void kvmppc_update_lpcr(struct kvm *kvm, unsigned long lpcr, |
| 185 | unsigned long mask); | 184 | unsigned long mask); |
| 185 | extern void kvmppc_set_fscr(struct kvm_vcpu *vcpu, u64 fscr); | ||
| 186 | 186 | ||
| 187 | extern void kvmppc_entry_trampoline(void); | 187 | extern void kvmppc_entry_trampoline(void); |
| 188 | extern void kvmppc_hv_entry_trampoline(void); | 188 | extern void kvmppc_hv_entry_trampoline(void); |
| 189 | extern u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst); | 189 | extern u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst); |
| 190 | extern ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst); | 190 | extern ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst); |
| 191 | extern int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd); | 191 | extern int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd); |
| 192 | extern void kvmppc_pr_init_default_hcalls(struct kvm *kvm); | ||
| 193 | extern int kvmppc_hcall_impl_pr(unsigned long cmd); | ||
| 194 | extern int kvmppc_hcall_impl_hv_realmode(unsigned long cmd); | ||
| 192 | extern void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu, | 195 | extern void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu, |
| 193 | struct kvm_vcpu *vcpu); | 196 | struct kvm_vcpu *vcpu); |
| 194 | extern void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu, | 197 | extern void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu, |
| @@ -274,32 +277,6 @@ static inline bool kvmppc_need_byteswap(struct kvm_vcpu *vcpu) | |||
| 274 | return (kvmppc_get_msr(vcpu) & MSR_LE) != (MSR_KERNEL & MSR_LE); | 277 | return (kvmppc_get_msr(vcpu) & MSR_LE) != (MSR_KERNEL & MSR_LE); |
| 275 | } | 278 | } |
| 276 | 279 | ||
| 277 | static inline u32 kvmppc_get_last_inst_internal(struct kvm_vcpu *vcpu, ulong pc) | ||
| 278 | { | ||
| 279 | /* Load the instruction manually if it failed to do so in the | ||
| 280 | * exit path */ | ||
| 281 | if (vcpu->arch.last_inst == KVM_INST_FETCH_FAILED) | ||
| 282 | kvmppc_ld(vcpu, &pc, sizeof(u32), &vcpu->arch.last_inst, false); | ||
| 283 | |||
| 284 | return kvmppc_need_byteswap(vcpu) ? swab32(vcpu->arch.last_inst) : | ||
| 285 | vcpu->arch.last_inst; | ||
| 286 | } | ||
| 287 | |||
| 288 | static inline u32 kvmppc_get_last_inst(struct kvm_vcpu *vcpu) | ||
| 289 | { | ||
| 290 | return kvmppc_get_last_inst_internal(vcpu, kvmppc_get_pc(vcpu)); | ||
| 291 | } | ||
| 292 | |||
| 293 | /* | ||
| 294 | * Like kvmppc_get_last_inst(), but for fetching a sc instruction. | ||
| 295 | * Because the sc instruction sets SRR0 to point to the following | ||
| 296 | * instruction, we have to fetch from pc - 4. | ||
| 297 | */ | ||
| 298 | static inline u32 kvmppc_get_last_sc(struct kvm_vcpu *vcpu) | ||
| 299 | { | ||
| 300 | return kvmppc_get_last_inst_internal(vcpu, kvmppc_get_pc(vcpu) - 4); | ||
| 301 | } | ||
| 302 | |||
| 303 | static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu) | 280 | static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu) |
| 304 | { | 281 | { |
| 305 | return vcpu->arch.fault_dar; | 282 | return vcpu->arch.fault_dar; |
| @@ -310,6 +287,13 @@ static inline bool is_kvmppc_resume_guest(int r) | |||
| 310 | return (r == RESUME_GUEST || r == RESUME_GUEST_NV); | 287 | return (r == RESUME_GUEST || r == RESUME_GUEST_NV); |
| 311 | } | 288 | } |
| 312 | 289 | ||
| 290 | static inline bool is_kvmppc_hv_enabled(struct kvm *kvm); | ||
| 291 | static inline bool kvmppc_supports_magic_page(struct kvm_vcpu *vcpu) | ||
| 292 | { | ||
| 293 | /* Only PR KVM supports the magic page */ | ||
| 294 | return !is_kvmppc_hv_enabled(vcpu->kvm); | ||
| 295 | } | ||
| 296 | |||
| 313 | /* Magic register values loaded into r3 and r4 before the 'sc' assembly | 297 | /* Magic register values loaded into r3 and r4 before the 'sc' assembly |
| 314 | * instruction for the OSI hypercalls */ | 298 | * instruction for the OSI hypercalls */ |
| 315 | #define OSI_SC_MAGIC_R3 0x113724FA | 299 | #define OSI_SC_MAGIC_R3 0x113724FA |
| @@ -322,4 +306,7 @@ static inline bool is_kvmppc_resume_guest(int r) | |||
| 322 | /* LPIDs we support with this build -- runtime limit may be lower */ | 306 | /* LPIDs we support with this build -- runtime limit may be lower */ |
| 323 | #define KVMPPC_NR_LPIDS (LPID_RSVD + 1) | 307 | #define KVMPPC_NR_LPIDS (LPID_RSVD + 1) |
| 324 | 308 | ||
| 309 | #define SPLIT_HACK_MASK 0xff000000 | ||
| 310 | #define SPLIT_HACK_OFFS 0xfb000000 | ||
| 311 | |||
| 325 | #endif /* __ASM_KVM_BOOK3S_H__ */ | 312 | #endif /* __ASM_KVM_BOOK3S_H__ */ |
diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h index d645428a65a4..0aa817933e6a 100644 --- a/arch/powerpc/include/asm/kvm_book3s_64.h +++ b/arch/powerpc/include/asm/kvm_book3s_64.h | |||
| @@ -59,20 +59,29 @@ extern unsigned long kvm_rma_pages; | |||
| 59 | /* These bits are reserved in the guest view of the HPTE */ | 59 | /* These bits are reserved in the guest view of the HPTE */ |
| 60 | #define HPTE_GR_RESERVED HPTE_GR_MODIFIED | 60 | #define HPTE_GR_RESERVED HPTE_GR_MODIFIED |
| 61 | 61 | ||
| 62 | static inline long try_lock_hpte(unsigned long *hpte, unsigned long bits) | 62 | static inline long try_lock_hpte(__be64 *hpte, unsigned long bits) |
| 63 | { | 63 | { |
| 64 | unsigned long tmp, old; | 64 | unsigned long tmp, old; |
| 65 | __be64 be_lockbit, be_bits; | ||
| 66 | |||
| 67 | /* | ||
| 68 | * We load/store in native endian, but the HTAB is in big endian. If | ||
| 69 | * we byte swap all data we apply on the PTE we're implicitly correct | ||
| 70 | * again. | ||
| 71 | */ | ||
| 72 | be_lockbit = cpu_to_be64(HPTE_V_HVLOCK); | ||
| 73 | be_bits = cpu_to_be64(bits); | ||
| 65 | 74 | ||
| 66 | asm volatile(" ldarx %0,0,%2\n" | 75 | asm volatile(" ldarx %0,0,%2\n" |
| 67 | " and. %1,%0,%3\n" | 76 | " and. %1,%0,%3\n" |
| 68 | " bne 2f\n" | 77 | " bne 2f\n" |
| 69 | " ori %0,%0,%4\n" | 78 | " or %0,%0,%4\n" |
| 70 | " stdcx. %0,0,%2\n" | 79 | " stdcx. %0,0,%2\n" |
| 71 | " beq+ 2f\n" | 80 | " beq+ 2f\n" |
| 72 | " mr %1,%3\n" | 81 | " mr %1,%3\n" |
| 73 | "2: isync" | 82 | "2: isync" |
| 74 | : "=&r" (tmp), "=&r" (old) | 83 | : "=&r" (tmp), "=&r" (old) |
| 75 | : "r" (hpte), "r" (bits), "i" (HPTE_V_HVLOCK) | 84 | : "r" (hpte), "r" (be_bits), "r" (be_lockbit) |
| 76 | : "cc", "memory"); | 85 | : "cc", "memory"); |
| 77 | return old == 0; | 86 | return old == 0; |
| 78 | } | 87 | } |
| @@ -110,16 +119,12 @@ static inline int __hpte_actual_psize(unsigned int lp, int psize) | |||
| 110 | static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r, | 119 | static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r, |
| 111 | unsigned long pte_index) | 120 | unsigned long pte_index) |
| 112 | { | 121 | { |
| 113 | int b_psize, a_psize; | 122 | int b_psize = MMU_PAGE_4K, a_psize = MMU_PAGE_4K; |
| 114 | unsigned int penc; | 123 | unsigned int penc; |
| 115 | unsigned long rb = 0, va_low, sllp; | 124 | unsigned long rb = 0, va_low, sllp; |
| 116 | unsigned int lp = (r >> LP_SHIFT) & ((1 << LP_BITS) - 1); | 125 | unsigned int lp = (r >> LP_SHIFT) & ((1 << LP_BITS) - 1); |
| 117 | 126 | ||
| 118 | if (!(v & HPTE_V_LARGE)) { | 127 | if (v & HPTE_V_LARGE) { |
| 119 | /* both base and actual psize is 4k */ | ||
| 120 | b_psize = MMU_PAGE_4K; | ||
| 121 | a_psize = MMU_PAGE_4K; | ||
| 122 | } else { | ||
| 123 | for (b_psize = 0; b_psize < MMU_PAGE_COUNT; b_psize++) { | 128 | for (b_psize = 0; b_psize < MMU_PAGE_COUNT; b_psize++) { |
| 124 | 129 | ||
| 125 | /* valid entries have a shift value */ | 130 | /* valid entries have a shift value */ |
| @@ -142,6 +147,8 @@ static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r, | |||
| 142 | */ | 147 | */ |
| 143 | /* This covers 14..54 bits of va*/ | 148 | /* This covers 14..54 bits of va*/ |
| 144 | rb = (v & ~0x7fUL) << 16; /* AVA field */ | 149 | rb = (v & ~0x7fUL) << 16; /* AVA field */ |
| 150 | |||
| 151 | rb |= v >> (62 - 8); /* B field */ | ||
| 145 | /* | 152 | /* |
| 146 | * AVA in v had cleared lower 23 bits. We need to derive | 153 | * AVA in v had cleared lower 23 bits. We need to derive |
| 147 | * that from pteg index | 154 | * that from pteg index |
| @@ -172,10 +179,10 @@ static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r, | |||
| 172 | { | 179 | { |
| 173 | int aval_shift; | 180 | int aval_shift; |
| 174 | /* | 181 | /* |
| 175 | * remaining 7bits of AVA/LP fields | 182 | * remaining bits of AVA/LP fields |
| 176 | * Also contain the rr bits of LP | 183 | * Also contain the rr bits of LP |
| 177 | */ | 184 | */ |
| 178 | rb |= (va_low & 0x7f) << 16; | 185 | rb |= (va_low << mmu_psize_defs[b_psize].shift) & 0x7ff000; |
| 179 | /* | 186 | /* |
| 180 | * Now clear not needed LP bits based on actual psize | 187 | * Now clear not needed LP bits based on actual psize |
| 181 | */ | 188 | */ |
diff --git a/arch/powerpc/include/asm/kvm_booke.h b/arch/powerpc/include/asm/kvm_booke.h index c7aed6105ff9..f7aa5cc395c4 100644 --- a/arch/powerpc/include/asm/kvm_booke.h +++ b/arch/powerpc/include/asm/kvm_booke.h | |||
| @@ -69,11 +69,6 @@ static inline bool kvmppc_need_byteswap(struct kvm_vcpu *vcpu) | |||
| 69 | return false; | 69 | return false; |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | static inline u32 kvmppc_get_last_inst(struct kvm_vcpu *vcpu) | ||
| 73 | { | ||
| 74 | return vcpu->arch.last_inst; | ||
| 75 | } | ||
| 76 | |||
| 77 | static inline void kvmppc_set_ctr(struct kvm_vcpu *vcpu, ulong val) | 72 | static inline void kvmppc_set_ctr(struct kvm_vcpu *vcpu, ulong val) |
| 78 | { | 73 | { |
| 79 | vcpu->arch.ctr = val; | 74 | vcpu->arch.ctr = val; |
| @@ -108,4 +103,14 @@ static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu) | |||
| 108 | { | 103 | { |
| 109 | return vcpu->arch.fault_dear; | 104 | return vcpu->arch.fault_dear; |
| 110 | } | 105 | } |
| 106 | |||
| 107 | static inline bool kvmppc_supports_magic_page(struct kvm_vcpu *vcpu) | ||
| 108 | { | ||
| 109 | /* Magic page is only supported on e500v2 */ | ||
| 110 | #ifdef CONFIG_KVM_E500V2 | ||
| 111 | return true; | ||
| 112 | #else | ||
| 113 | return false; | ||
| 114 | #endif | ||
| 115 | } | ||
| 111 | #endif /* __ASM_KVM_BOOKE_H__ */ | 116 | #endif /* __ASM_KVM_BOOKE_H__ */ |
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index bb66d8b8efdf..98d9dd50d063 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <asm/processor.h> | 34 | #include <asm/processor.h> |
| 35 | #include <asm/page.h> | 35 | #include <asm/page.h> |
| 36 | #include <asm/cacheflush.h> | 36 | #include <asm/cacheflush.h> |
| 37 | #include <asm/hvcall.h> | ||
| 37 | 38 | ||
| 38 | #define KVM_MAX_VCPUS NR_CPUS | 39 | #define KVM_MAX_VCPUS NR_CPUS |
| 39 | #define KVM_MAX_VCORES NR_CPUS | 40 | #define KVM_MAX_VCORES NR_CPUS |
| @@ -48,7 +49,6 @@ | |||
| 48 | #define KVM_NR_IRQCHIPS 1 | 49 | #define KVM_NR_IRQCHIPS 1 |
| 49 | #define KVM_IRQCHIP_NUM_PINS 256 | 50 | #define KVM_IRQCHIP_NUM_PINS 256 |
| 50 | 51 | ||
| 51 | #if !defined(CONFIG_KVM_440) | ||
| 52 | #include <linux/mmu_notifier.h> | 52 | #include <linux/mmu_notifier.h> |
| 53 | 53 | ||
| 54 | #define KVM_ARCH_WANT_MMU_NOTIFIER | 54 | #define KVM_ARCH_WANT_MMU_NOTIFIER |
| @@ -61,8 +61,6 @@ extern int kvm_age_hva(struct kvm *kvm, unsigned long hva); | |||
| 61 | extern int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); | 61 | extern int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); |
| 62 | extern void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); | 62 | extern void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); |
| 63 | 63 | ||
| 64 | #endif | ||
| 65 | |||
| 66 | #define HPTEG_CACHE_NUM (1 << 15) | 64 | #define HPTEG_CACHE_NUM (1 << 15) |
| 67 | #define HPTEG_HASH_BITS_PTE 13 | 65 | #define HPTEG_HASH_BITS_PTE 13 |
| 68 | #define HPTEG_HASH_BITS_PTE_LONG 12 | 66 | #define HPTEG_HASH_BITS_PTE_LONG 12 |
| @@ -96,7 +94,6 @@ struct kvm_vm_stat { | |||
| 96 | struct kvm_vcpu_stat { | 94 | struct kvm_vcpu_stat { |
| 97 | u32 sum_exits; | 95 | u32 sum_exits; |
| 98 | u32 mmio_exits; | 96 | u32 mmio_exits; |
| 99 | u32 dcr_exits; | ||
| 100 | u32 signal_exits; | 97 | u32 signal_exits; |
| 101 | u32 light_exits; | 98 | u32 light_exits; |
| 102 | /* Account for special types of light exits: */ | 99 | /* Account for special types of light exits: */ |
| @@ -113,22 +110,21 @@ struct kvm_vcpu_stat { | |||
| 113 | u32 halt_wakeup; | 110 | u32 halt_wakeup; |
| 114 | u32 dbell_exits; | 111 | u32 dbell_exits; |
| 115 | u32 gdbell_exits; | 112 | u32 gdbell_exits; |
| 113 | u32 ld; | ||
| 114 | u32 st; | ||
| 116 | #ifdef CONFIG_PPC_BOOK3S | 115 | #ifdef CONFIG_PPC_BOOK3S |
| 117 | u32 pf_storage; | 116 | u32 pf_storage; |
| 118 | u32 pf_instruc; | 117 | u32 pf_instruc; |
| 119 | u32 sp_storage; | 118 | u32 sp_storage; |
| 120 | u32 sp_instruc; | 119 | u32 sp_instruc; |
| 121 | u32 queue_intr; | 120 | u32 queue_intr; |
| 122 | u32 ld; | ||
| 123 | u32 ld_slow; | 121 | u32 ld_slow; |
| 124 | u32 st; | ||
| 125 | u32 st_slow; | 122 | u32 st_slow; |
| 126 | #endif | 123 | #endif |
| 127 | }; | 124 | }; |
| 128 | 125 | ||
| 129 | enum kvm_exit_types { | 126 | enum kvm_exit_types { |
| 130 | MMIO_EXITS, | 127 | MMIO_EXITS, |
| 131 | DCR_EXITS, | ||
| 132 | SIGNAL_EXITS, | 128 | SIGNAL_EXITS, |
| 133 | ITLB_REAL_MISS_EXITS, | 129 | ITLB_REAL_MISS_EXITS, |
| 134 | ITLB_VIRT_MISS_EXITS, | 130 | ITLB_VIRT_MISS_EXITS, |
| @@ -254,7 +250,6 @@ struct kvm_arch { | |||
| 254 | atomic_t hpte_mod_interest; | 250 | atomic_t hpte_mod_interest; |
| 255 | spinlock_t slot_phys_lock; | 251 | spinlock_t slot_phys_lock; |
| 256 | cpumask_t need_tlb_flush; | 252 | cpumask_t need_tlb_flush; |
| 257 | struct kvmppc_vcore *vcores[KVM_MAX_VCORES]; | ||
| 258 | int hpt_cma_alloc; | 253 | int hpt_cma_alloc; |
| 259 | #endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */ | 254 | #endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */ |
| 260 | #ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE | 255 | #ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE |
| @@ -263,6 +258,7 @@ struct kvm_arch { | |||
| 263 | #ifdef CONFIG_PPC_BOOK3S_64 | 258 | #ifdef CONFIG_PPC_BOOK3S_64 |
| 264 | struct list_head spapr_tce_tables; | 259 | struct list_head spapr_tce_tables; |
| 265 | struct list_head rtas_tokens; | 260 | struct list_head rtas_tokens; |
| 261 | DECLARE_BITMAP(enabled_hcalls, MAX_HCALL_OPCODE/4 + 1); | ||
| 266 | #endif | 262 | #endif |
| 267 | #ifdef CONFIG_KVM_MPIC | 263 | #ifdef CONFIG_KVM_MPIC |
| 268 | struct openpic *mpic; | 264 | struct openpic *mpic; |
| @@ -271,6 +267,10 @@ struct kvm_arch { | |||
| 271 | struct kvmppc_xics *xics; | 267 | struct kvmppc_xics *xics; |
| 272 | #endif | 268 | #endif |
| 273 | struct kvmppc_ops *kvm_ops; | 269 | struct kvmppc_ops *kvm_ops; |
| 270 | #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE | ||
| 271 | /* This array can grow quite large, keep it at the end */ | ||
| 272 | struct kvmppc_vcore *vcores[KVM_MAX_VCORES]; | ||
| 273 | #endif | ||
| 274 | }; | 274 | }; |
| 275 | 275 | ||
| 276 | /* | 276 | /* |
| @@ -305,6 +305,8 @@ struct kvmppc_vcore { | |||
| 305 | u32 arch_compat; | 305 | u32 arch_compat; |
| 306 | ulong pcr; | 306 | ulong pcr; |
| 307 | ulong dpdes; /* doorbell state (POWER8) */ | 307 | ulong dpdes; /* doorbell state (POWER8) */ |
| 308 | void *mpp_buffer; /* Micro Partition Prefetch buffer */ | ||
| 309 | bool mpp_buffer_is_valid; | ||
| 308 | }; | 310 | }; |
| 309 | 311 | ||
| 310 | #define VCORE_ENTRY_COUNT(vc) ((vc)->entry_exit_count & 0xff) | 312 | #define VCORE_ENTRY_COUNT(vc) ((vc)->entry_exit_count & 0xff) |
| @@ -503,8 +505,10 @@ struct kvm_vcpu_arch { | |||
| 503 | #ifdef CONFIG_BOOKE | 505 | #ifdef CONFIG_BOOKE |
| 504 | u32 decar; | 506 | u32 decar; |
| 505 | #endif | 507 | #endif |
| 506 | u32 tbl; | 508 | /* Time base value when we entered the guest */ |
| 507 | u32 tbu; | 509 | u64 entry_tb; |
| 510 | u64 entry_vtb; | ||
| 511 | u64 entry_ic; | ||
| 508 | u32 tcr; | 512 | u32 tcr; |
| 509 | ulong tsr; /* we need to perform set/clr_bits() which requires ulong */ | 513 | ulong tsr; /* we need to perform set/clr_bits() which requires ulong */ |
| 510 | u32 ivor[64]; | 514 | u32 ivor[64]; |
| @@ -580,6 +584,8 @@ struct kvm_vcpu_arch { | |||
| 580 | u32 mmucfg; | 584 | u32 mmucfg; |
| 581 | u32 eptcfg; | 585 | u32 eptcfg; |
| 582 | u32 epr; | 586 | u32 epr; |
| 587 | u64 sprg9; | ||
| 588 | u32 pwrmgtcr0; | ||
| 583 | u32 crit_save; | 589 | u32 crit_save; |
| 584 | /* guest debug registers*/ | 590 | /* guest debug registers*/ |
| 585 | struct debug_reg dbg_reg; | 591 | struct debug_reg dbg_reg; |
| @@ -593,8 +599,6 @@ struct kvm_vcpu_arch { | |||
| 593 | u8 io_gpr; /* GPR used as IO source/target */ | 599 | u8 io_gpr; /* GPR used as IO source/target */ |
| 594 | u8 mmio_is_bigendian; | 600 | u8 mmio_is_bigendian; |
| 595 | u8 mmio_sign_extend; | 601 | u8 mmio_sign_extend; |
| 596 | u8 dcr_needed; | ||
| 597 | u8 dcr_is_write; | ||
| 598 | u8 osi_needed; | 602 | u8 osi_needed; |
| 599 | u8 osi_enabled; | 603 | u8 osi_enabled; |
| 600 | u8 papr_enabled; | 604 | u8 papr_enabled; |
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 9c89cdd067a6..fb86a2299d8a 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h | |||
| @@ -41,12 +41,26 @@ | |||
| 41 | enum emulation_result { | 41 | enum emulation_result { |
| 42 | EMULATE_DONE, /* no further processing */ | 42 | EMULATE_DONE, /* no further processing */ |
| 43 | EMULATE_DO_MMIO, /* kvm_run filled with MMIO request */ | 43 | EMULATE_DO_MMIO, /* kvm_run filled with MMIO request */ |
| 44 | EMULATE_DO_DCR, /* kvm_run filled with DCR request */ | ||
| 45 | EMULATE_FAIL, /* can't emulate this instruction */ | 44 | EMULATE_FAIL, /* can't emulate this instruction */ |
| 46 | EMULATE_AGAIN, /* something went wrong. go again */ | 45 | EMULATE_AGAIN, /* something went wrong. go again */ |
| 47 | EMULATE_EXIT_USER, /* emulation requires exit to user-space */ | 46 | EMULATE_EXIT_USER, /* emulation requires exit to user-space */ |
| 48 | }; | 47 | }; |
| 49 | 48 | ||
| 49 | enum instruction_type { | ||
| 50 | INST_GENERIC, | ||
| 51 | INST_SC, /* system call */ | ||
| 52 | }; | ||
| 53 | |||
| 54 | enum xlate_instdata { | ||
| 55 | XLATE_INST, /* translate instruction address */ | ||
| 56 | XLATE_DATA /* translate data address */ | ||
| 57 | }; | ||
| 58 | |||
| 59 | enum xlate_readwrite { | ||
| 60 | XLATE_READ, /* check for read permissions */ | ||
| 61 | XLATE_WRITE /* check for write permissions */ | ||
| 62 | }; | ||
| 63 | |||
| 50 | extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); | 64 | extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); |
| 51 | extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); | 65 | extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); |
| 52 | extern void kvmppc_handler_highmem(void); | 66 | extern void kvmppc_handler_highmem(void); |
| @@ -62,8 +76,16 @@ extern int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
| 62 | u64 val, unsigned int bytes, | 76 | u64 val, unsigned int bytes, |
| 63 | int is_default_endian); | 77 | int is_default_endian); |
| 64 | 78 | ||
| 79 | extern int kvmppc_load_last_inst(struct kvm_vcpu *vcpu, | ||
| 80 | enum instruction_type type, u32 *inst); | ||
| 81 | |||
| 82 | extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, | ||
| 83 | bool data); | ||
| 84 | extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, | ||
| 85 | bool data); | ||
| 65 | extern int kvmppc_emulate_instruction(struct kvm_run *run, | 86 | extern int kvmppc_emulate_instruction(struct kvm_run *run, |
| 66 | struct kvm_vcpu *vcpu); | 87 | struct kvm_vcpu *vcpu); |
| 88 | extern int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu); | ||
| 67 | extern int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu); | 89 | extern int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu); |
| 68 | extern void kvmppc_emulate_dec(struct kvm_vcpu *vcpu); | 90 | extern void kvmppc_emulate_dec(struct kvm_vcpu *vcpu); |
| 69 | extern u32 kvmppc_get_dec(struct kvm_vcpu *vcpu, u64 tb); | 91 | extern u32 kvmppc_get_dec(struct kvm_vcpu *vcpu, u64 tb); |
| @@ -86,6 +108,9 @@ extern gpa_t kvmppc_mmu_xlate(struct kvm_vcpu *vcpu, unsigned int gtlb_index, | |||
| 86 | gva_t eaddr); | 108 | gva_t eaddr); |
| 87 | extern void kvmppc_mmu_dtlb_miss(struct kvm_vcpu *vcpu); | 109 | extern void kvmppc_mmu_dtlb_miss(struct kvm_vcpu *vcpu); |
| 88 | extern void kvmppc_mmu_itlb_miss(struct kvm_vcpu *vcpu); | 110 | extern void kvmppc_mmu_itlb_miss(struct kvm_vcpu *vcpu); |
| 111 | extern int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, | ||
| 112 | enum xlate_instdata xlid, enum xlate_readwrite xlrw, | ||
| 113 | struct kvmppc_pte *pte); | ||
| 89 | 114 | ||
| 90 | extern struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, | 115 | extern struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, |
| 91 | unsigned int id); | 116 | unsigned int id); |
| @@ -106,6 +131,14 @@ extern void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu); | |||
| 106 | extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu, | 131 | extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu, |
| 107 | struct kvm_interrupt *irq); | 132 | struct kvm_interrupt *irq); |
| 108 | extern void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu); | 133 | extern void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu); |
| 134 | extern void kvmppc_core_queue_dtlb_miss(struct kvm_vcpu *vcpu, ulong dear_flags, | ||
| 135 | ulong esr_flags); | ||
| 136 | extern void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu, | ||
| 137 | ulong dear_flags, | ||
| 138 | ulong esr_flags); | ||
| 139 | extern void kvmppc_core_queue_itlb_miss(struct kvm_vcpu *vcpu); | ||
| 140 | extern void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu, | ||
| 141 | ulong esr_flags); | ||
| 109 | extern void kvmppc_core_flush_tlb(struct kvm_vcpu *vcpu); | 142 | extern void kvmppc_core_flush_tlb(struct kvm_vcpu *vcpu); |
| 110 | extern int kvmppc_core_check_requests(struct kvm_vcpu *vcpu); | 143 | extern int kvmppc_core_check_requests(struct kvm_vcpu *vcpu); |
| 111 | 144 | ||
| @@ -228,12 +261,35 @@ struct kvmppc_ops { | |||
| 228 | void (*fast_vcpu_kick)(struct kvm_vcpu *vcpu); | 261 | void (*fast_vcpu_kick)(struct kvm_vcpu *vcpu); |
| 229 | long (*arch_vm_ioctl)(struct file *filp, unsigned int ioctl, | 262 | long (*arch_vm_ioctl)(struct file *filp, unsigned int ioctl, |
| 230 | unsigned long arg); | 263 | unsigned long arg); |
| 231 | 264 | int (*hcall_implemented)(unsigned long hcall); | |
| 232 | }; | 265 | }; |
| 233 | 266 | ||
| 234 | extern struct kvmppc_ops *kvmppc_hv_ops; | 267 | extern struct kvmppc_ops *kvmppc_hv_ops; |
| 235 | extern struct kvmppc_ops *kvmppc_pr_ops; | 268 | extern struct kvmppc_ops *kvmppc_pr_ops; |
| 236 | 269 | ||
| 270 | static inline int kvmppc_get_last_inst(struct kvm_vcpu *vcpu, | ||
| 271 | enum instruction_type type, u32 *inst) | ||
| 272 | { | ||
| 273 | int ret = EMULATE_DONE; | ||
| 274 | u32 fetched_inst; | ||
| 275 | |||
| 276 | /* Load the instruction manually if it failed to do so in the | ||
| 277 | * exit path */ | ||
| 278 | if (vcpu->arch.last_inst == KVM_INST_FETCH_FAILED) | ||
| 279 | ret = kvmppc_load_last_inst(vcpu, type, &vcpu->arch.last_inst); | ||
| 280 | |||
| 281 | /* Write fetch_failed unswapped if the fetch failed */ | ||
| 282 | if (ret == EMULATE_DONE) | ||
| 283 | fetched_inst = kvmppc_need_byteswap(vcpu) ? | ||
| 284 | swab32(vcpu->arch.last_inst) : | ||
| 285 | vcpu->arch.last_inst; | ||
| 286 | else | ||
| 287 | fetched_inst = vcpu->arch.last_inst; | ||
| 288 | |||
| 289 | *inst = fetched_inst; | ||
| 290 | return ret; | ||
| 291 | } | ||
| 292 | |||
| 237 | static inline bool is_kvmppc_hv_enabled(struct kvm *kvm) | 293 | static inline bool is_kvmppc_hv_enabled(struct kvm *kvm) |
| 238 | { | 294 | { |
| 239 | return kvm->arch.kvm_ops == kvmppc_hv_ops; | 295 | return kvm->arch.kvm_ops == kvmppc_hv_ops; |
| @@ -392,6 +448,17 @@ static inline int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd) | |||
| 392 | { return 0; } | 448 | { return 0; } |
| 393 | #endif | 449 | #endif |
| 394 | 450 | ||
| 451 | static inline unsigned long kvmppc_get_epr(struct kvm_vcpu *vcpu) | ||
| 452 | { | ||
| 453 | #ifdef CONFIG_KVM_BOOKE_HV | ||
| 454 | return mfspr(SPRN_GEPR); | ||
| 455 | #elif defined(CONFIG_BOOKE) | ||
| 456 | return vcpu->arch.epr; | ||
| 457 | #else | ||
| 458 | return 0; | ||
| 459 | #endif | ||
| 460 | } | ||
| 461 | |||
| 395 | static inline void kvmppc_set_epr(struct kvm_vcpu *vcpu, u32 epr) | 462 | static inline void kvmppc_set_epr(struct kvm_vcpu *vcpu, u32 epr) |
| 396 | { | 463 | { |
| 397 | #ifdef CONFIG_KVM_BOOKE_HV | 464 | #ifdef CONFIG_KVM_BOOKE_HV |
| @@ -472,8 +539,20 @@ static inline bool kvmppc_shared_big_endian(struct kvm_vcpu *vcpu) | |||
| 472 | #endif | 539 | #endif |
| 473 | } | 540 | } |
| 474 | 541 | ||
| 542 | #define SPRNG_WRAPPER_GET(reg, bookehv_spr) \ | ||
| 543 | static inline ulong kvmppc_get_##reg(struct kvm_vcpu *vcpu) \ | ||
| 544 | { \ | ||
| 545 | return mfspr(bookehv_spr); \ | ||
| 546 | } \ | ||
| 547 | |||
| 548 | #define SPRNG_WRAPPER_SET(reg, bookehv_spr) \ | ||
| 549 | static inline void kvmppc_set_##reg(struct kvm_vcpu *vcpu, ulong val) \ | ||
| 550 | { \ | ||
| 551 | mtspr(bookehv_spr, val); \ | ||
| 552 | } \ | ||
| 553 | |||
| 475 | #define SHARED_WRAPPER_GET(reg, size) \ | 554 | #define SHARED_WRAPPER_GET(reg, size) \ |
| 476 | static inline u##size kvmppc_get_##reg(struct kvm_vcpu *vcpu) \ | 555 | static inline u##size kvmppc_get_##reg(struct kvm_vcpu *vcpu) \ |
| 477 | { \ | 556 | { \ |
| 478 | if (kvmppc_shared_big_endian(vcpu)) \ | 557 | if (kvmppc_shared_big_endian(vcpu)) \ |
| 479 | return be##size##_to_cpu(vcpu->arch.shared->reg); \ | 558 | return be##size##_to_cpu(vcpu->arch.shared->reg); \ |
| @@ -494,14 +573,31 @@ static inline void kvmppc_set_##reg(struct kvm_vcpu *vcpu, u##size val) \ | |||
| 494 | SHARED_WRAPPER_GET(reg, size) \ | 573 | SHARED_WRAPPER_GET(reg, size) \ |
| 495 | SHARED_WRAPPER_SET(reg, size) \ | 574 | SHARED_WRAPPER_SET(reg, size) \ |
| 496 | 575 | ||
| 576 | #define SPRNG_WRAPPER(reg, bookehv_spr) \ | ||
| 577 | SPRNG_WRAPPER_GET(reg, bookehv_spr) \ | ||
| 578 | SPRNG_WRAPPER_SET(reg, bookehv_spr) \ | ||
| 579 | |||
| 580 | #ifdef CONFIG_KVM_BOOKE_HV | ||
| 581 | |||
| 582 | #define SHARED_SPRNG_WRAPPER(reg, size, bookehv_spr) \ | ||
| 583 | SPRNG_WRAPPER(reg, bookehv_spr) \ | ||
| 584 | |||
| 585 | #else | ||
| 586 | |||
| 587 | #define SHARED_SPRNG_WRAPPER(reg, size, bookehv_spr) \ | ||
| 588 | SHARED_WRAPPER(reg, size) \ | ||
| 589 | |||
| 590 | #endif | ||
| 591 | |||
| 497 | SHARED_WRAPPER(critical, 64) | 592 | SHARED_WRAPPER(critical, 64) |
| 498 | SHARED_WRAPPER(sprg0, 64) | 593 | SHARED_SPRNG_WRAPPER(sprg0, 64, SPRN_GSPRG0) |
| 499 | SHARED_WRAPPER(sprg1, 64) | 594 | SHARED_SPRNG_WRAPPER(sprg1, 64, SPRN_GSPRG1) |
| 500 | SHARED_WRAPPER(sprg2, 64) | 595 | SHARED_SPRNG_WRAPPER(sprg2, 64, SPRN_GSPRG2) |
| 501 | SHARED_WRAPPER(sprg3, 64) | 596 | SHARED_SPRNG_WRAPPER(sprg3, 64, SPRN_GSPRG3) |
| 502 | SHARED_WRAPPER(srr0, 64) | 597 | SHARED_SPRNG_WRAPPER(srr0, 64, SPRN_GSRR0) |
| 503 | SHARED_WRAPPER(srr1, 64) | 598 | SHARED_SPRNG_WRAPPER(srr1, 64, SPRN_GSRR1) |
| 504 | SHARED_WRAPPER(dar, 64) | 599 | SHARED_SPRNG_WRAPPER(dar, 64, SPRN_GDEAR) |
| 600 | SHARED_SPRNG_WRAPPER(esr, 64, SPRN_GESR) | ||
| 505 | SHARED_WRAPPER_GET(msr, 64) | 601 | SHARED_WRAPPER_GET(msr, 64) |
| 506 | static inline void kvmppc_set_msr_fast(struct kvm_vcpu *vcpu, u64 val) | 602 | static inline void kvmppc_set_msr_fast(struct kvm_vcpu *vcpu, u64 val) |
| 507 | { | 603 | { |
diff --git a/arch/powerpc/include/asm/mmu-book3e.h b/arch/powerpc/include/asm/mmu-book3e.h index d0918e09557f..cd4f04a74802 100644 --- a/arch/powerpc/include/asm/mmu-book3e.h +++ b/arch/powerpc/include/asm/mmu-book3e.h | |||
| @@ -40,7 +40,11 @@ | |||
| 40 | 40 | ||
| 41 | /* MAS registers bit definitions */ | 41 | /* MAS registers bit definitions */ |
| 42 | 42 | ||
| 43 | #define MAS0_TLBSEL(x) (((x) << 28) & 0x30000000) | 43 | #define MAS0_TLBSEL_MASK 0x30000000 |
| 44 | #define MAS0_TLBSEL_SHIFT 28 | ||
| 45 | #define MAS0_TLBSEL(x) (((x) << MAS0_TLBSEL_SHIFT) & MAS0_TLBSEL_MASK) | ||
| 46 | #define MAS0_GET_TLBSEL(mas0) (((mas0) & MAS0_TLBSEL_MASK) >> \ | ||
| 47 | MAS0_TLBSEL_SHIFT) | ||
| 44 | #define MAS0_ESEL_MASK 0x0FFF0000 | 48 | #define MAS0_ESEL_MASK 0x0FFF0000 |
| 45 | #define MAS0_ESEL_SHIFT 16 | 49 | #define MAS0_ESEL_SHIFT 16 |
| 46 | #define MAS0_ESEL(x) (((x) << MAS0_ESEL_SHIFT) & MAS0_ESEL_MASK) | 50 | #define MAS0_ESEL(x) (((x) << MAS0_ESEL_SHIFT) & MAS0_ESEL_MASK) |
| @@ -58,6 +62,7 @@ | |||
| 58 | #define MAS1_TSIZE_MASK 0x00000f80 | 62 | #define MAS1_TSIZE_MASK 0x00000f80 |
| 59 | #define MAS1_TSIZE_SHIFT 7 | 63 | #define MAS1_TSIZE_SHIFT 7 |
| 60 | #define MAS1_TSIZE(x) (((x) << MAS1_TSIZE_SHIFT) & MAS1_TSIZE_MASK) | 64 | #define MAS1_TSIZE(x) (((x) << MAS1_TSIZE_SHIFT) & MAS1_TSIZE_MASK) |
| 65 | #define MAS1_GET_TSIZE(mas1) (((mas1) & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT) | ||
| 61 | 66 | ||
| 62 | #define MAS2_EPN (~0xFFFUL) | 67 | #define MAS2_EPN (~0xFFFUL) |
| 63 | #define MAS2_X0 0x00000040 | 68 | #define MAS2_X0 0x00000040 |
| @@ -86,6 +91,7 @@ | |||
| 86 | #define MAS3_SPSIZE 0x0000003e | 91 | #define MAS3_SPSIZE 0x0000003e |
| 87 | #define MAS3_SPSIZE_SHIFT 1 | 92 | #define MAS3_SPSIZE_SHIFT 1 |
| 88 | 93 | ||
| 94 | #define MAS4_TLBSEL_MASK MAS0_TLBSEL_MASK | ||
| 89 | #define MAS4_TLBSELD(x) MAS0_TLBSEL(x) | 95 | #define MAS4_TLBSELD(x) MAS0_TLBSEL(x) |
| 90 | #define MAS4_INDD 0x00008000 /* Default IND */ | 96 | #define MAS4_INDD 0x00008000 /* Default IND */ |
| 91 | #define MAS4_TSIZED(x) MAS1_TSIZE(x) | 97 | #define MAS4_TSIZED(x) MAS1_TSIZE(x) |
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index e316dad6ba76..6f8536208049 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h | |||
| @@ -139,6 +139,7 @@ | |||
| 139 | #define PPC_INST_ISEL 0x7c00001e | 139 | #define PPC_INST_ISEL 0x7c00001e |
| 140 | #define PPC_INST_ISEL_MASK 0xfc00003e | 140 | #define PPC_INST_ISEL_MASK 0xfc00003e |
| 141 | #define PPC_INST_LDARX 0x7c0000a8 | 141 | #define PPC_INST_LDARX 0x7c0000a8 |
| 142 | #define PPC_INST_LOGMPP 0x7c0007e4 | ||
| 142 | #define PPC_INST_LSWI 0x7c0004aa | 143 | #define PPC_INST_LSWI 0x7c0004aa |
| 143 | #define PPC_INST_LSWX 0x7c00042a | 144 | #define PPC_INST_LSWX 0x7c00042a |
| 144 | #define PPC_INST_LWARX 0x7c000028 | 145 | #define PPC_INST_LWARX 0x7c000028 |
| @@ -277,6 +278,20 @@ | |||
| 277 | #define __PPC_EH(eh) 0 | 278 | #define __PPC_EH(eh) 0 |
| 278 | #endif | 279 | #endif |
| 279 | 280 | ||
| 281 | /* POWER8 Micro Partition Prefetch (MPP) parameters */ | ||
| 282 | /* Address mask is common for LOGMPP instruction and MPPR SPR */ | ||
| 283 | #define PPC_MPPE_ADDRESS_MASK 0xffffffffc000 | ||
| 284 | |||
| 285 | /* Bits 60 and 61 of MPP SPR should be set to one of the following */ | ||
| 286 | /* Aborting the fetch is indeed setting 00 in the table size bits */ | ||
| 287 | #define PPC_MPPR_FETCH_ABORT (0x0ULL << 60) | ||
| 288 | #define PPC_MPPR_FETCH_WHOLE_TABLE (0x2ULL << 60) | ||
| 289 | |||
| 290 | /* Bits 54 and 55 of register for LOGMPP instruction should be set to: */ | ||
| 291 | #define PPC_LOGMPP_LOG_L2 (0x02ULL << 54) | ||
| 292 | #define PPC_LOGMPP_LOG_L2L3 (0x01ULL << 54) | ||
| 293 | #define PPC_LOGMPP_LOG_ABORT (0x03ULL << 54) | ||
| 294 | |||
| 280 | /* Deal with instructions that older assemblers aren't aware of */ | 295 | /* Deal with instructions that older assemblers aren't aware of */ |
| 281 | #define PPC_DCBAL(a, b) stringify_in_c(.long PPC_INST_DCBAL | \ | 296 | #define PPC_DCBAL(a, b) stringify_in_c(.long PPC_INST_DCBAL | \ |
| 282 | __PPC_RA(a) | __PPC_RB(b)) | 297 | __PPC_RA(a) | __PPC_RB(b)) |
| @@ -285,6 +300,8 @@ | |||
| 285 | #define PPC_LDARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LDARX | \ | 300 | #define PPC_LDARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LDARX | \ |
| 286 | ___PPC_RT(t) | ___PPC_RA(a) | \ | 301 | ___PPC_RT(t) | ___PPC_RA(a) | \ |
| 287 | ___PPC_RB(b) | __PPC_EH(eh)) | 302 | ___PPC_RB(b) | __PPC_EH(eh)) |
| 303 | #define PPC_LOGMPP(b) stringify_in_c(.long PPC_INST_LOGMPP | \ | ||
| 304 | __PPC_RB(b)) | ||
| 288 | #define PPC_LWARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LWARX | \ | 305 | #define PPC_LWARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LWARX | \ |
| 289 | ___PPC_RT(t) | ___PPC_RA(a) | \ | 306 | ___PPC_RT(t) | ___PPC_RA(a) | \ |
| 290 | ___PPC_RB(b) | __PPC_EH(eh)) | 307 | ___PPC_RB(b) | __PPC_EH(eh)) |
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index f7b97b895708..1c987bf794ef 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h | |||
| @@ -225,6 +225,7 @@ | |||
| 225 | #define CTRL_TE 0x00c00000 /* thread enable */ | 225 | #define CTRL_TE 0x00c00000 /* thread enable */ |
| 226 | #define CTRL_RUNLATCH 0x1 | 226 | #define CTRL_RUNLATCH 0x1 |
| 227 | #define SPRN_DAWR 0xB4 | 227 | #define SPRN_DAWR 0xB4 |
| 228 | #define SPRN_MPPR 0xB8 /* Micro Partition Prefetch Register */ | ||
| 228 | #define SPRN_RPR 0xBA /* Relative Priority Register */ | 229 | #define SPRN_RPR 0xBA /* Relative Priority Register */ |
| 229 | #define SPRN_CIABR 0xBB | 230 | #define SPRN_CIABR 0xBB |
| 230 | #define CIABR_PRIV 0x3 | 231 | #define CIABR_PRIV 0x3 |
| @@ -944,9 +945,6 @@ | |||
| 944 | * readable variant for reads, which can avoid a fault | 945 | * readable variant for reads, which can avoid a fault |
| 945 | * with KVM type virtualization. | 946 | * with KVM type virtualization. |
| 946 | * | 947 | * |
| 947 | * (*) Under KVM, the host SPRG1 is used to point to | ||
| 948 | * the current VCPU data structure | ||
| 949 | * | ||
| 950 | * 32-bit 8xx: | 948 | * 32-bit 8xx: |
| 951 | * - SPRG0 scratch for exception vectors | 949 | * - SPRG0 scratch for exception vectors |
| 952 | * - SPRG1 scratch for exception vectors | 950 | * - SPRG1 scratch for exception vectors |
| @@ -1203,6 +1201,15 @@ | |||
| 1203 | : "r" ((unsigned long)(v)) \ | 1201 | : "r" ((unsigned long)(v)) \ |
| 1204 | : "memory") | 1202 | : "memory") |
| 1205 | 1203 | ||
| 1204 | static inline unsigned long mfvtb (void) | ||
| 1205 | { | ||
| 1206 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
| 1207 | if (cpu_has_feature(CPU_FTR_ARCH_207S)) | ||
| 1208 | return mfspr(SPRN_VTB); | ||
| 1209 | #endif | ||
| 1210 | return 0; | ||
| 1211 | } | ||
| 1212 | |||
| 1206 | #ifdef __powerpc64__ | 1213 | #ifdef __powerpc64__ |
| 1207 | #if defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_FSL_BOOK3E) | 1214 | #if defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_FSL_BOOK3E) |
| 1208 | #define mftb() ({unsigned long rval; \ | 1215 | #define mftb() ({unsigned long rval; \ |
diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h index 1d428e6007ca..03cbada59d3a 100644 --- a/arch/powerpc/include/asm/time.h +++ b/arch/powerpc/include/asm/time.h | |||
| @@ -102,6 +102,15 @@ static inline u64 get_rtc(void) | |||
| 102 | return (u64)hi * 1000000000 + lo; | 102 | return (u64)hi * 1000000000 + lo; |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | static inline u64 get_vtb(void) | ||
| 106 | { | ||
| 107 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
| 108 | if (cpu_has_feature(CPU_FTR_ARCH_207S)) | ||
| 109 | return mfvtb(); | ||
| 110 | #endif | ||
| 111 | return 0; | ||
| 112 | } | ||
| 113 | |||
| 105 | #ifdef CONFIG_PPC64 | 114 | #ifdef CONFIG_PPC64 |
| 106 | static inline u64 get_tb(void) | 115 | static inline u64 get_tb(void) |
| 107 | { | 116 | { |
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index 2bc4a9409a93..e0e49dbb145d 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h | |||
| @@ -548,6 +548,7 @@ struct kvm_get_htab_header { | |||
| 548 | 548 | ||
| 549 | #define KVM_REG_PPC_VRSAVE (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb4) | 549 | #define KVM_REG_PPC_VRSAVE (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb4) |
| 550 | #define KVM_REG_PPC_LPCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb5) | 550 | #define KVM_REG_PPC_LPCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb5) |
| 551 | #define KVM_REG_PPC_LPCR_64 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb5) | ||
| 551 | #define KVM_REG_PPC_PPR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb6) | 552 | #define KVM_REG_PPC_PPR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb6) |
| 552 | 553 | ||
| 553 | /* Architecture compatibility level */ | 554 | /* Architecture compatibility level */ |
| @@ -555,6 +556,7 @@ struct kvm_get_htab_header { | |||
| 555 | 556 | ||
| 556 | #define KVM_REG_PPC_DABRX (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb8) | 557 | #define KVM_REG_PPC_DABRX (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb8) |
| 557 | #define KVM_REG_PPC_WORT (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb9) | 558 | #define KVM_REG_PPC_WORT (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb9) |
| 559 | #define KVM_REG_PPC_SPRG9 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xba) | ||
| 558 | 560 | ||
| 559 | /* Transactional Memory checkpointed state: | 561 | /* Transactional Memory checkpointed state: |
| 560 | * This is all GPRs, all VSX regs and a subset of SPRs | 562 | * This is all GPRs, all VSX regs and a subset of SPRs |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index e35054054c32..9d7dede2847c 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
| @@ -491,6 +491,7 @@ int main(void) | |||
| 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)); | 492 | DEFINE(KVM_TLBIE_LOCK, offsetof(struct kvm, arch.tlbie_lock)); |
| 493 | DEFINE(KVM_NEED_FLUSH, offsetof(struct kvm, arch.need_tlb_flush.bits)); | 493 | DEFINE(KVM_NEED_FLUSH, offsetof(struct kvm, arch.need_tlb_flush.bits)); |
| 494 | DEFINE(KVM_ENABLED_HCALLS, offsetof(struct kvm, arch.enabled_hcalls)); | ||
| 494 | DEFINE(KVM_LPCR, offsetof(struct kvm, arch.lpcr)); | 495 | DEFINE(KVM_LPCR, offsetof(struct kvm, arch.lpcr)); |
| 495 | DEFINE(KVM_RMOR, offsetof(struct kvm, arch.rmor)); | 496 | DEFINE(KVM_RMOR, offsetof(struct kvm, arch.rmor)); |
| 496 | DEFINE(KVM_VRMA_SLB_V, offsetof(struct kvm, arch.vrma_slb_v)); | 497 | DEFINE(KVM_VRMA_SLB_V, offsetof(struct kvm, arch.vrma_slb_v)); |
| @@ -665,6 +666,7 @@ int main(void) | |||
| 665 | DEFINE(VCPU_LR, offsetof(struct kvm_vcpu, arch.lr)); | 666 | DEFINE(VCPU_LR, offsetof(struct kvm_vcpu, arch.lr)); |
| 666 | DEFINE(VCPU_CTR, offsetof(struct kvm_vcpu, arch.ctr)); | 667 | DEFINE(VCPU_CTR, offsetof(struct kvm_vcpu, arch.ctr)); |
| 667 | DEFINE(VCPU_PC, offsetof(struct kvm_vcpu, arch.pc)); | 668 | DEFINE(VCPU_PC, offsetof(struct kvm_vcpu, arch.pc)); |
| 669 | DEFINE(VCPU_SPRG9, offsetof(struct kvm_vcpu, arch.sprg9)); | ||
| 668 | DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst)); | 670 | DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst)); |
| 669 | DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear)); | 671 | DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear)); |
| 670 | DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr)); | 672 | DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr)); |
diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c deleted file mode 100644 index 9cb4b0a36031..000000000000 --- a/arch/powerpc/kvm/44x.c +++ /dev/null | |||
| @@ -1,237 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify | ||
| 3 | * it under the terms of the GNU General Public License, version 2, as | ||
| 4 | * published by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * This program is distributed in the hope that it will be useful, | ||
| 7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 9 | * GNU General Public License for more details. | ||
| 10 | * | ||
| 11 | * You should have received a copy of the GNU General Public License | ||
| 12 | * along with this program; if not, write to the Free Software | ||
| 13 | * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 14 | * | ||
| 15 | * Copyright IBM Corp. 2008 | ||
| 16 | * | ||
| 17 | * Authors: Hollis Blanchard <hollisb@us.ibm.com> | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/kvm_host.h> | ||
| 21 | #include <linux/slab.h> | ||
| 22 | #include <linux/err.h> | ||
| 23 | #include <linux/export.h> | ||
| 24 | #include <linux/module.h> | ||
| 25 | #include <linux/miscdevice.h> | ||
| 26 | |||
| 27 | #include <asm/reg.h> | ||
| 28 | #include <asm/cputable.h> | ||
| 29 | #include <asm/tlbflush.h> | ||
| 30 | #include <asm/kvm_44x.h> | ||
| 31 | #include <asm/kvm_ppc.h> | ||
| 32 | |||
| 33 | #include "44x_tlb.h" | ||
| 34 | #include "booke.h" | ||
| 35 | |||
| 36 | static void kvmppc_core_vcpu_load_44x(struct kvm_vcpu *vcpu, int cpu) | ||
| 37 | { | ||
| 38 | kvmppc_booke_vcpu_load(vcpu, cpu); | ||
| 39 | kvmppc_44x_tlb_load(vcpu); | ||
| 40 | } | ||
| 41 | |||
| 42 | static void kvmppc_core_vcpu_put_44x(struct kvm_vcpu *vcpu) | ||
| 43 | { | ||
| 44 | kvmppc_44x_tlb_put(vcpu); | ||
| 45 | kvmppc_booke_vcpu_put(vcpu); | ||
| 46 | } | ||
| 47 | |||
| 48 | int kvmppc_core_check_processor_compat(void) | ||
| 49 | { | ||
| 50 | int r; | ||
| 51 | |||
| 52 | if (strncmp(cur_cpu_spec->platform, "ppc440", 6) == 0) | ||
| 53 | r = 0; | ||
| 54 | else | ||
| 55 | r = -ENOTSUPP; | ||
| 56 | |||
| 57 | return r; | ||
| 58 | } | ||
| 59 | |||
| 60 | int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu) | ||
| 61 | { | ||
| 62 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
| 63 | struct kvmppc_44x_tlbe *tlbe = &vcpu_44x->guest_tlb[0]; | ||
| 64 | int i; | ||
| 65 | |||
| 66 | tlbe->tid = 0; | ||
| 67 | tlbe->word0 = PPC44x_TLB_16M | PPC44x_TLB_VALID; | ||
| 68 | tlbe->word1 = 0; | ||
| 69 | tlbe->word2 = PPC44x_TLB_SX | PPC44x_TLB_SW | PPC44x_TLB_SR; | ||
| 70 | |||
| 71 | tlbe++; | ||
| 72 | tlbe->tid = 0; | ||
| 73 | tlbe->word0 = 0xef600000 | PPC44x_TLB_4K | PPC44x_TLB_VALID; | ||
| 74 | tlbe->word1 = 0xef600000; | ||
| 75 | tlbe->word2 = PPC44x_TLB_SX | PPC44x_TLB_SW | PPC44x_TLB_SR | ||
| 76 | | PPC44x_TLB_I | PPC44x_TLB_G; | ||
| 77 | |||
| 78 | /* Since the guest can directly access the timebase, it must know the | ||
| 79 | * real timebase frequency. Accordingly, it must see the state of | ||
| 80 | * CCR1[TCS]. */ | ||
| 81 | /* XXX CCR1 doesn't exist on all 440 SoCs. */ | ||
| 82 | vcpu->arch.ccr1 = mfspr(SPRN_CCR1); | ||
| 83 | |||
| 84 | for (i = 0; i < ARRAY_SIZE(vcpu_44x->shadow_refs); i++) | ||
| 85 | vcpu_44x->shadow_refs[i].gtlb_index = -1; | ||
| 86 | |||
| 87 | vcpu->arch.cpu_type = KVM_CPU_440; | ||
| 88 | vcpu->arch.pvr = mfspr(SPRN_PVR); | ||
| 89 | |||
| 90 | return 0; | ||
| 91 | } | ||
| 92 | |||
| 93 | /* 'linear_address' is actually an encoding of AS|PID|EADDR . */ | ||
| 94 | int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu, | ||
| 95 | struct kvm_translation *tr) | ||
| 96 | { | ||
| 97 | int index; | ||
| 98 | gva_t eaddr; | ||
| 99 | u8 pid; | ||
| 100 | u8 as; | ||
| 101 | |||
| 102 | eaddr = tr->linear_address; | ||
| 103 | pid = (tr->linear_address >> 32) & 0xff; | ||
| 104 | as = (tr->linear_address >> 40) & 0x1; | ||
| 105 | |||
| 106 | index = kvmppc_44x_tlb_index(vcpu, eaddr, pid, as); | ||
| 107 | if (index == -1) { | ||
| 108 | tr->valid = 0; | ||
| 109 | return 0; | ||
| 110 | } | ||
| 111 | |||
| 112 | tr->physical_address = kvmppc_mmu_xlate(vcpu, index, eaddr); | ||
| 113 | /* XXX what does "writeable" and "usermode" even mean? */ | ||
| 114 | tr->valid = 1; | ||
| 115 | |||
| 116 | return 0; | ||
| 117 | } | ||
| 118 | |||
| 119 | static int kvmppc_core_get_sregs_44x(struct kvm_vcpu *vcpu, | ||
| 120 | struct kvm_sregs *sregs) | ||
| 121 | { | ||
| 122 | return kvmppc_get_sregs_ivor(vcpu, sregs); | ||
| 123 | } | ||
| 124 | |||
| 125 | static int kvmppc_core_set_sregs_44x(struct kvm_vcpu *vcpu, | ||
| 126 | struct kvm_sregs *sregs) | ||
| 127 | { | ||
| 128 | return kvmppc_set_sregs_ivor(vcpu, sregs); | ||
| 129 | } | ||
| 130 | |||
| 131 | static int kvmppc_get_one_reg_44x(struct kvm_vcpu *vcpu, u64 id, | ||
| 132 | union kvmppc_one_reg *val) | ||
| 133 | { | ||
| 134 | return -EINVAL; | ||
| 135 | } | ||
| 136 | |||
| 137 | static int kvmppc_set_one_reg_44x(struct kvm_vcpu *vcpu, u64 id, | ||
| 138 | union kvmppc_one_reg *val) | ||
| 139 | { | ||
| 140 | return -EINVAL; | ||
| 141 | } | ||
| 142 | |||
| 143 | static struct kvm_vcpu *kvmppc_core_vcpu_create_44x(struct kvm *kvm, | ||
| 144 | unsigned int id) | ||
| 145 | { | ||
| 146 | struct kvmppc_vcpu_44x *vcpu_44x; | ||
| 147 | struct kvm_vcpu *vcpu; | ||
| 148 | int err; | ||
| 149 | |||
| 150 | vcpu_44x = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL); | ||
| 151 | if (!vcpu_44x) { | ||
| 152 | err = -ENOMEM; | ||
| 153 | goto out; | ||
| 154 | } | ||
| 155 | |||
| 156 | vcpu = &vcpu_44x->vcpu; | ||
| 157 | err = kvm_vcpu_init(vcpu, kvm, id); | ||
| 158 | if (err) | ||
| 159 | goto free_vcpu; | ||
| 160 | |||
| 161 | vcpu->arch.shared = (void*)__get_free_page(GFP_KERNEL|__GFP_ZERO); | ||
| 162 | if (!vcpu->arch.shared) | ||
| 163 | goto uninit_vcpu; | ||
| 164 | |||
| 165 | return vcpu; | ||
| 166 | |||
| 167 | uninit_vcpu: | ||
| 168 | kvm_vcpu_uninit(vcpu); | ||
| 169 | free_vcpu: | ||
| 170 | kmem_cache_free(kvm_vcpu_cache, vcpu_44x); | ||
| 171 | out: | ||
| 172 | return ERR_PTR(err); | ||
| 173 | } | ||
| 174 | |||
| 175 | static void kvmppc_core_vcpu_free_44x(struct kvm_vcpu *vcpu) | ||
| 176 | { | ||
| 177 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
| 178 | |||
| 179 | free_page((unsigned long)vcpu->arch.shared); | ||
| 180 | kvm_vcpu_uninit(vcpu); | ||
| 181 | kmem_cache_free(kvm_vcpu_cache, vcpu_44x); | ||
| 182 | } | ||
| 183 | |||
| 184 | static int kvmppc_core_init_vm_44x(struct kvm *kvm) | ||
| 185 | { | ||
| 186 | return 0; | ||
| 187 | } | ||
| 188 | |||
| 189 | static void kvmppc_core_destroy_vm_44x(struct kvm *kvm) | ||
| 190 | { | ||
| 191 | } | ||
| 192 | |||
| 193 | static struct kvmppc_ops kvm_ops_44x = { | ||
| 194 | .get_sregs = kvmppc_core_get_sregs_44x, | ||
| 195 | .set_sregs = kvmppc_core_set_sregs_44x, | ||
| 196 | .get_one_reg = kvmppc_get_one_reg_44x, | ||
| 197 | .set_one_reg = kvmppc_set_one_reg_44x, | ||
| 198 | .vcpu_load = kvmppc_core_vcpu_load_44x, | ||
| 199 | .vcpu_put = kvmppc_core_vcpu_put_44x, | ||
| 200 | .vcpu_create = kvmppc_core_vcpu_create_44x, | ||
| 201 | .vcpu_free = kvmppc_core_vcpu_free_44x, | ||
| 202 | .mmu_destroy = kvmppc_mmu_destroy_44x, | ||
| 203 | .init_vm = kvmppc_core_init_vm_44x, | ||
| 204 | .destroy_vm = kvmppc_core_destroy_vm_44x, | ||
| 205 | .emulate_op = kvmppc_core_emulate_op_44x, | ||
| 206 | .emulate_mtspr = kvmppc_core_emulate_mtspr_44x, | ||
| 207 | .emulate_mfspr = kvmppc_core_emulate_mfspr_44x, | ||
| 208 | }; | ||
| 209 | |||
| 210 | static int __init kvmppc_44x_init(void) | ||
| 211 | { | ||
| 212 | int r; | ||
| 213 | |||
| 214 | r = kvmppc_booke_init(); | ||
| 215 | if (r) | ||
| 216 | goto err_out; | ||
| 217 | |||
| 218 | r = kvm_init(NULL, sizeof(struct kvmppc_vcpu_44x), 0, THIS_MODULE); | ||
| 219 | if (r) | ||
| 220 | goto err_out; | ||
| 221 | kvm_ops_44x.owner = THIS_MODULE; | ||
| 222 | kvmppc_pr_ops = &kvm_ops_44x; | ||
| 223 | |||
| 224 | err_out: | ||
| 225 | return r; | ||
| 226 | } | ||
| 227 | |||
| 228 | static void __exit kvmppc_44x_exit(void) | ||
| 229 | { | ||
| 230 | kvmppc_pr_ops = NULL; | ||
| 231 | kvmppc_booke_exit(); | ||
| 232 | } | ||
| 233 | |||
| 234 | module_init(kvmppc_44x_init); | ||
| 235 | module_exit(kvmppc_44x_exit); | ||
| 236 | MODULE_ALIAS_MISCDEV(KVM_MINOR); | ||
| 237 | MODULE_ALIAS("devname:kvm"); | ||
diff --git a/arch/powerpc/kvm/44x_emulate.c b/arch/powerpc/kvm/44x_emulate.c deleted file mode 100644 index 92c9ab4bcfec..000000000000 --- a/arch/powerpc/kvm/44x_emulate.c +++ /dev/null | |||
| @@ -1,194 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify | ||
| 3 | * it under the terms of the GNU General Public License, version 2, as | ||
| 4 | * published by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * This program is distributed in the hope that it will be useful, | ||
| 7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 9 | * GNU General Public License for more details. | ||
| 10 | * | ||
| 11 | * You should have received a copy of the GNU General Public License | ||
| 12 | * along with this program; if not, write to the Free Software | ||
| 13 | * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 14 | * | ||
| 15 | * Copyright IBM Corp. 2008 | ||
| 16 | * | ||
| 17 | * Authors: Hollis Blanchard <hollisb@us.ibm.com> | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <asm/kvm_ppc.h> | ||
| 21 | #include <asm/dcr.h> | ||
| 22 | #include <asm/dcr-regs.h> | ||
| 23 | #include <asm/disassemble.h> | ||
| 24 | #include <asm/kvm_44x.h> | ||
| 25 | #include "timing.h" | ||
| 26 | |||
| 27 | #include "booke.h" | ||
| 28 | #include "44x_tlb.h" | ||
| 29 | |||
| 30 | #define XOP_MFDCRX 259 | ||
| 31 | #define XOP_MFDCR 323 | ||
| 32 | #define XOP_MTDCRX 387 | ||
| 33 | #define XOP_MTDCR 451 | ||
| 34 | #define XOP_TLBSX 914 | ||
| 35 | #define XOP_ICCCI 966 | ||
| 36 | #define XOP_TLBWE 978 | ||
| 37 | |||
| 38 | static int emulate_mtdcr(struct kvm_vcpu *vcpu, int rs, int dcrn) | ||
| 39 | { | ||
| 40 | /* emulate some access in kernel */ | ||
| 41 | switch (dcrn) { | ||
| 42 | case DCRN_CPR0_CONFIG_ADDR: | ||
| 43 | vcpu->arch.cpr0_cfgaddr = kvmppc_get_gpr(vcpu, rs); | ||
| 44 | return EMULATE_DONE; | ||
| 45 | default: | ||
| 46 | vcpu->run->dcr.dcrn = dcrn; | ||
| 47 | vcpu->run->dcr.data = kvmppc_get_gpr(vcpu, rs); | ||
| 48 | vcpu->run->dcr.is_write = 1; | ||
| 49 | vcpu->arch.dcr_is_write = 1; | ||
| 50 | vcpu->arch.dcr_needed = 1; | ||
| 51 | kvmppc_account_exit(vcpu, DCR_EXITS); | ||
| 52 | return EMULATE_DO_DCR; | ||
| 53 | } | ||
| 54 | } | ||
| 55 | |||
| 56 | static int emulate_mfdcr(struct kvm_vcpu *vcpu, int rt, int dcrn) | ||
| 57 | { | ||
| 58 | /* The guest may access CPR0 registers to determine the timebase | ||
| 59 | * frequency, and it must know the real host frequency because it | ||
| 60 | * can directly access the timebase registers. | ||
| 61 | * | ||
| 62 | * It would be possible to emulate those accesses in userspace, | ||
| 63 | * but userspace can really only figure out the end frequency. | ||
| 64 | * We could decompose that into the factors that compute it, but | ||
| 65 | * that's tricky math, and it's easier to just report the real | ||
| 66 | * CPR0 values. | ||
| 67 | */ | ||
| 68 | switch (dcrn) { | ||
| 69 | case DCRN_CPR0_CONFIG_ADDR: | ||
| 70 | kvmppc_set_gpr(vcpu, rt, vcpu->arch.cpr0_cfgaddr); | ||
| 71 | break; | ||
| 72 | case DCRN_CPR0_CONFIG_DATA: | ||
| 73 | local_irq_disable(); | ||
| 74 | mtdcr(DCRN_CPR0_CONFIG_ADDR, | ||
| 75 | vcpu->arch.cpr0_cfgaddr); | ||
| 76 | kvmppc_set_gpr(vcpu, rt, | ||
| 77 | mfdcr(DCRN_CPR0_CONFIG_DATA)); | ||
| 78 | local_irq_enable(); | ||
| 79 | break; | ||
| 80 | default: | ||
| 81 | vcpu->run->dcr.dcrn = dcrn; | ||
| 82 | vcpu->run->dcr.data = 0; | ||
| 83 | vcpu->run->dcr.is_write = 0; | ||
| 84 | vcpu->arch.dcr_is_write = 0; | ||
| 85 | vcpu->arch.io_gpr = rt; | ||
| 86 | vcpu->arch.dcr_needed = 1; | ||
| 87 | kvmppc_account_exit(vcpu, DCR_EXITS); | ||
| 88 | return EMULATE_DO_DCR; | ||
| 89 | } | ||
| 90 | |||
| 91 | return EMULATE_DONE; | ||
| 92 | } | ||
| 93 | |||
| 94 | int kvmppc_core_emulate_op_44x(struct kvm_run *run, struct kvm_vcpu *vcpu, | ||
| 95 | unsigned int inst, int *advance) | ||
| 96 | { | ||
| 97 | int emulated = EMULATE_DONE; | ||
| 98 | int dcrn = get_dcrn(inst); | ||
| 99 | int ra = get_ra(inst); | ||
| 100 | int rb = get_rb(inst); | ||
| 101 | int rc = get_rc(inst); | ||
| 102 | int rs = get_rs(inst); | ||
| 103 | int rt = get_rt(inst); | ||
| 104 | int ws = get_ws(inst); | ||
| 105 | |||
| 106 | switch (get_op(inst)) { | ||
| 107 | case 31: | ||
| 108 | switch (get_xop(inst)) { | ||
| 109 | |||
| 110 | case XOP_MFDCR: | ||
| 111 | emulated = emulate_mfdcr(vcpu, rt, dcrn); | ||
| 112 | break; | ||
| 113 | |||
| 114 | case XOP_MFDCRX: | ||
| 115 | emulated = emulate_mfdcr(vcpu, rt, | ||
| 116 | kvmppc_get_gpr(vcpu, ra)); | ||
| 117 | break; | ||
| 118 | |||
| 119 | case XOP_MTDCR: | ||
| 120 | emulated = emulate_mtdcr(vcpu, rs, dcrn); | ||
| 121 | break; | ||
| 122 | |||
| 123 | case XOP_MTDCRX: | ||
| 124 | emulated = emulate_mtdcr(vcpu, rs, | ||
| 125 | kvmppc_get_gpr(vcpu, ra)); | ||
| 126 | break; | ||
| 127 | |||
| 128 | case XOP_TLBWE: | ||
| 129 | emulated = kvmppc_44x_emul_tlbwe(vcpu, ra, rs, ws); | ||
| 130 | break; | ||
| 131 | |||
| 132 | case XOP_TLBSX: | ||
| 133 | emulated = kvmppc_44x_emul_tlbsx(vcpu, rt, ra, rb, rc); | ||
| 134 | break; | ||
| 135 | |||
| 136 | case XOP_ICCCI: | ||
| 137 | break; | ||
| 138 | |||
| 139 | default: | ||
| 140 | emulated = EMULATE_FAIL; | ||
| 141 | } | ||
| 142 | |||
| 143 | break; | ||
| 144 | |||
| 145 | default: | ||
| 146 | emulated = EMULATE_FAIL; | ||
| 147 | } | ||
| 148 | |||
| 149 | if (emulated == EMULATE_FAIL) | ||
| 150 | emulated = kvmppc_booke_emulate_op(run, vcpu, inst, advance); | ||
| 151 | |||
| 152 | return emulated; | ||
| 153 | } | ||
| 154 | |||
| 155 | int kvmppc_core_emulate_mtspr_44x(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) | ||
| 156 | { | ||
| 157 | int emulated = EMULATE_DONE; | ||
| 158 | |||
| 159 | switch (sprn) { | ||
| 160 | case SPRN_PID: | ||
| 161 | kvmppc_set_pid(vcpu, spr_val); break; | ||
| 162 | case SPRN_MMUCR: | ||
| 163 | vcpu->arch.mmucr = spr_val; break; | ||
| 164 | case SPRN_CCR0: | ||
| 165 | vcpu->arch.ccr0 = spr_val; break; | ||
| 166 | case SPRN_CCR1: | ||
| 167 | vcpu->arch.ccr1 = spr_val; break; | ||
| 168 | default: | ||
| 169 | emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, spr_val); | ||
| 170 | } | ||
| 171 | |||
| 172 | return emulated; | ||
| 173 | } | ||
| 174 | |||
| 175 | int kvmppc_core_emulate_mfspr_44x(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) | ||
| 176 | { | ||
| 177 | int emulated = EMULATE_DONE; | ||
| 178 | |||
| 179 | switch (sprn) { | ||
| 180 | case SPRN_PID: | ||
| 181 | *spr_val = vcpu->arch.pid; break; | ||
| 182 | case SPRN_MMUCR: | ||
| 183 | *spr_val = vcpu->arch.mmucr; break; | ||
| 184 | case SPRN_CCR0: | ||
| 185 | *spr_val = vcpu->arch.ccr0; break; | ||
| 186 | case SPRN_CCR1: | ||
| 187 | *spr_val = vcpu->arch.ccr1; break; | ||
| 188 | default: | ||
| 189 | emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, spr_val); | ||
| 190 | } | ||
| 191 | |||
| 192 | return emulated; | ||
| 193 | } | ||
| 194 | |||
diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c deleted file mode 100644 index 0deef1082e02..000000000000 --- a/arch/powerpc/kvm/44x_tlb.c +++ /dev/null | |||
| @@ -1,528 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify | ||
| 3 | * it under the terms of the GNU General Public License, version 2, as | ||
| 4 | * published by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * This program is distributed in the hope that it will be useful, | ||
| 7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 9 | * GNU General Public License for more details. | ||
| 10 | * | ||
| 11 | * You should have received a copy of the GNU General Public License | ||
| 12 | * along with this program; if not, write to the Free Software | ||
| 13 | * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 14 | * | ||
| 15 | * Copyright IBM Corp. 2007 | ||
| 16 | * | ||
| 17 | * Authors: Hollis Blanchard <hollisb@us.ibm.com> | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/types.h> | ||
| 21 | #include <linux/string.h> | ||
| 22 | #include <linux/kvm.h> | ||
| 23 | #include <linux/kvm_host.h> | ||
| 24 | #include <linux/highmem.h> | ||
| 25 | |||
| 26 | #include <asm/tlbflush.h> | ||
| 27 | #include <asm/mmu-44x.h> | ||
| 28 | #include <asm/kvm_ppc.h> | ||
| 29 | #include <asm/kvm_44x.h> | ||
| 30 | #include "timing.h" | ||
| 31 | |||
| 32 | #include "44x_tlb.h" | ||
| 33 | #include "trace.h" | ||
| 34 | |||
| 35 | #ifndef PPC44x_TLBE_SIZE | ||
| 36 | #define PPC44x_TLBE_SIZE PPC44x_TLB_4K | ||
| 37 | #endif | ||
| 38 | |||
| 39 | #define PAGE_SIZE_4K (1<<12) | ||
| 40 | #define PAGE_MASK_4K (~(PAGE_SIZE_4K - 1)) | ||
| 41 | |||
| 42 | #define PPC44x_TLB_UATTR_MASK \ | ||
| 43 | (PPC44x_TLB_U0|PPC44x_TLB_U1|PPC44x_TLB_U2|PPC44x_TLB_U3) | ||
| 44 | #define PPC44x_TLB_USER_PERM_MASK (PPC44x_TLB_UX|PPC44x_TLB_UR|PPC44x_TLB_UW) | ||
| 45 | #define PPC44x_TLB_SUPER_PERM_MASK (PPC44x_TLB_SX|PPC44x_TLB_SR|PPC44x_TLB_SW) | ||
| 46 | |||
| 47 | #ifdef DEBUG | ||
| 48 | void kvmppc_dump_tlbs(struct kvm_vcpu *vcpu) | ||
| 49 | { | ||
| 50 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
| 51 | struct kvmppc_44x_tlbe *tlbe; | ||
| 52 | int i; | ||
| 53 | |||
| 54 | printk("vcpu %d TLB dump:\n", vcpu->vcpu_id); | ||
| 55 | printk("| %2s | %3s | %8s | %8s | %8s |\n", | ||
| 56 | "nr", "tid", "word0", "word1", "word2"); | ||
| 57 | |||
| 58 | for (i = 0; i < ARRAY_SIZE(vcpu_44x->guest_tlb); i++) { | ||
| 59 | tlbe = &vcpu_44x->guest_tlb[i]; | ||
| 60 | if (tlbe->word0 & PPC44x_TLB_VALID) | ||
| 61 | printk(" G%2d | %02X | %08X | %08X | %08X |\n", | ||
| 62 | i, tlbe->tid, tlbe->word0, tlbe->word1, | ||
| 63 | tlbe->word2); | ||
| 64 | } | ||
| 65 | } | ||
| 66 | #endif | ||
| 67 | |||
| 68 | static inline void kvmppc_44x_tlbie(unsigned int index) | ||
| 69 | { | ||
| 70 | /* 0 <= index < 64, so the V bit is clear and we can use the index as | ||
| 71 | * word0. */ | ||
| 72 | asm volatile( | ||
| 73 | "tlbwe %[index], %[index], 0\n" | ||
| 74 | : | ||
| 75 | : [index] "r"(index) | ||
| 76 | ); | ||
| 77 | } | ||
| 78 | |||
| 79 | static inline void kvmppc_44x_tlbre(unsigned int index, | ||
| 80 | struct kvmppc_44x_tlbe *tlbe) | ||
| 81 | { | ||
| 82 | asm volatile( | ||
| 83 | "tlbre %[word0], %[index], 0\n" | ||
| 84 | "mfspr %[tid], %[sprn_mmucr]\n" | ||
| 85 | "andi. %[tid], %[tid], 0xff\n" | ||
| 86 | "tlbre %[word1], %[index], 1\n" | ||
| 87 | "tlbre %[word2], %[index], 2\n" | ||
| 88 | : [word0] "=r"(tlbe->word0), | ||
| 89 | [word1] "=r"(tlbe->word1), | ||
| 90 | [word2] "=r"(tlbe->word2), | ||
| 91 | [tid] "=r"(tlbe->tid) | ||
| 92 | : [index] "r"(index), | ||
| 93 | [sprn_mmucr] "i"(SPRN_MMUCR) | ||
| 94 | : "cc" | ||
| 95 | ); | ||
| 96 | } | ||
| 97 | |||
| 98 | static inline void kvmppc_44x_tlbwe(unsigned int index, | ||
| 99 | struct kvmppc_44x_tlbe *stlbe) | ||
| 100 | { | ||
| 101 | unsigned long tmp; | ||
| 102 | |||
| 103 | asm volatile( | ||
| 104 | "mfspr %[tmp], %[sprn_mmucr]\n" | ||
| 105 | "rlwimi %[tmp], %[tid], 0, 0xff\n" | ||
| 106 | "mtspr %[sprn_mmucr], %[tmp]\n" | ||
| 107 | "tlbwe %[word0], %[index], 0\n" | ||
| 108 | "tlbwe %[word1], %[index], 1\n" | ||
| 109 | "tlbwe %[word2], %[index], 2\n" | ||
| 110 | : [tmp] "=&r"(tmp) | ||
| 111 | : [word0] "r"(stlbe->word0), | ||
| 112 | [word1] "r"(stlbe->word1), | ||
| 113 | [word2] "r"(stlbe->word2), | ||
| 114 | [tid] "r"(stlbe->tid), | ||
| 115 | [index] "r"(index), | ||
| 116 | [sprn_mmucr] "i"(SPRN_MMUCR) | ||
| 117 | ); | ||
| 118 | } | ||
| 119 | |||
| 120 | static u32 kvmppc_44x_tlb_shadow_attrib(u32 attrib, int usermode) | ||
| 121 | { | ||
| 122 | /* We only care about the guest's permission and user bits. */ | ||
| 123 | attrib &= PPC44x_TLB_PERM_MASK|PPC44x_TLB_UATTR_MASK; | ||
| 124 | |||
| 125 | if (!usermode) { | ||
| 126 | /* Guest is in supervisor mode, so we need to translate guest | ||
| 127 | * supervisor permissions into user permissions. */ | ||
| 128 | attrib &= ~PPC44x_TLB_USER_PERM_MASK; | ||
| 129 | attrib |= (attrib & PPC44x_TLB_SUPER_PERM_MASK) << 3; | ||
| 130 | } | ||
| 131 | |||
| 132 | /* Make sure host can always access this memory. */ | ||
| 133 | attrib |= PPC44x_TLB_SX|PPC44x_TLB_SR|PPC44x_TLB_SW; | ||
| 134 | |||
| 135 | /* WIMGE = 0b00100 */ | ||
| 136 | attrib |= PPC44x_TLB_M; | ||
| 137 | |||
| 138 | return attrib; | ||
| 139 | } | ||
| 140 | |||
| 141 | /* Load shadow TLB back into hardware. */ | ||
| 142 | void kvmppc_44x_tlb_load(struct kvm_vcpu *vcpu) | ||
| 143 | { | ||
| 144 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
| 145 | int i; | ||
| 146 | |||
| 147 | for (i = 0; i <= tlb_44x_hwater; i++) { | ||
| 148 | struct kvmppc_44x_tlbe *stlbe = &vcpu_44x->shadow_tlb[i]; | ||
| 149 | |||
| 150 | if (get_tlb_v(stlbe) && get_tlb_ts(stlbe)) | ||
| 151 | kvmppc_44x_tlbwe(i, stlbe); | ||
| 152 | } | ||
| 153 | } | ||
| 154 | |||
| 155 | static void kvmppc_44x_tlbe_set_modified(struct kvmppc_vcpu_44x *vcpu_44x, | ||
| 156 | unsigned int i) | ||
| 157 | { | ||
| 158 | vcpu_44x->shadow_tlb_mod[i] = 1; | ||
| 159 | } | ||
| 160 | |||
| 161 | /* Save hardware TLB to the vcpu, and invalidate all guest mappings. */ | ||
| 162 | void kvmppc_44x_tlb_put(struct kvm_vcpu *vcpu) | ||
| 163 | { | ||
| 164 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
| 165 | int i; | ||
| 166 | |||
| 167 | for (i = 0; i <= tlb_44x_hwater; i++) { | ||
| 168 | struct kvmppc_44x_tlbe *stlbe = &vcpu_44x->shadow_tlb[i]; | ||
| 169 | |||
| 170 | if (vcpu_44x->shadow_tlb_mod[i]) | ||
| 171 | kvmppc_44x_tlbre(i, stlbe); | ||
| 172 | |||
| 173 | if (get_tlb_v(stlbe) && get_tlb_ts(stlbe)) | ||
| 174 | kvmppc_44x_tlbie(i); | ||
| 175 | } | ||
| 176 | } | ||
| 177 | |||
| 178 | |||
| 179 | /* Search the guest TLB for a matching entry. */ | ||
| 180 | int kvmppc_44x_tlb_index(struct kvm_vcpu *vcpu, gva_t eaddr, unsigned int pid, | ||
| 181 | unsigned int as) | ||
| 182 | { | ||
| 183 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
| 184 | int i; | ||
| 185 | |||
| 186 | /* XXX Replace loop with fancy data structures. */ | ||
| 187 | for (i = 0; i < ARRAY_SIZE(vcpu_44x->guest_tlb); i++) { | ||
| 188 | struct kvmppc_44x_tlbe *tlbe = &vcpu_44x->guest_tlb[i]; | ||
| 189 | unsigned int tid; | ||
| 190 | |||
| 191 | if (eaddr < get_tlb_eaddr(tlbe)) | ||
| 192 | continue; | ||
| 193 | |||
| 194 | if (eaddr > get_tlb_end(tlbe)) | ||
| 195 | continue; | ||
| 196 | |||
| 197 | tid = get_tlb_tid(tlbe); | ||
| 198 | if (tid && (tid != pid)) | ||
| 199 | continue; | ||
| 200 | |||
| 201 | if (!get_tlb_v(tlbe)) | ||
| 202 | continue; | ||
| 203 | |||
| 204 | if (get_tlb_ts(tlbe) != as) | ||
| 205 | continue; | ||
| 206 | |||
| 207 | return i; | ||
| 208 | } | ||
| 209 | |||
| 210 | return -1; | ||
| 211 | } | ||
| 212 | |||
| 213 | gpa_t kvmppc_mmu_xlate(struct kvm_vcpu *vcpu, unsigned int gtlb_index, | ||
| 214 | gva_t eaddr) | ||
| 215 | { | ||
| 216 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
| 217 | struct kvmppc_44x_tlbe *gtlbe = &vcpu_44x->guest_tlb[gtlb_index]; | ||
| 218 | unsigned int pgmask = get_tlb_bytes(gtlbe) - 1; | ||
| 219 | |||
| 220 | return get_tlb_raddr(gtlbe) | (eaddr & pgmask); | ||
| 221 | } | ||
| 222 | |||
| 223 | int kvmppc_mmu_itlb_index(struct kvm_vcpu *vcpu, gva_t eaddr) | ||
| 224 | { | ||
| 225 | unsigned int as = !!(vcpu->arch.shared->msr & MSR_IS); | ||
| 226 | |||
| 227 | return kvmppc_44x_tlb_index(vcpu, eaddr, vcpu->arch.pid, as); | ||
| 228 | } | ||
| 229 | |||
| 230 | int kvmppc_mmu_dtlb_index(struct kvm_vcpu *vcpu, gva_t eaddr) | ||
| 231 | { | ||
| 232 | unsigned int as = !!(vcpu->arch.shared->msr & MSR_DS); | ||
| 233 | |||
| 234 | return kvmppc_44x_tlb_index(vcpu, eaddr, vcpu->arch.pid, as); | ||
| 235 | } | ||
| 236 | |||
| 237 | void kvmppc_mmu_itlb_miss(struct kvm_vcpu *vcpu) | ||
| 238 | { | ||
| 239 | } | ||
| 240 | |||
| 241 | void kvmppc_mmu_dtlb_miss(struct kvm_vcpu *vcpu) | ||
| 242 | { | ||
| 243 | } | ||
| 244 | |||
| 245 | static void kvmppc_44x_shadow_release(struct kvmppc_vcpu_44x *vcpu_44x, | ||
| 246 | unsigned int stlb_index) | ||
| 247 | { | ||
| 248 | struct kvmppc_44x_shadow_ref *ref = &vcpu_44x->shadow_refs[stlb_index]; | ||
| 249 | |||
| 250 | if (!ref->page) | ||
| 251 | return; | ||
| 252 | |||
| 253 | /* Discard from the TLB. */ | ||
| 254 | /* Note: we could actually invalidate a host mapping, if the host overwrote | ||
| 255 | * this TLB entry since we inserted a guest mapping. */ | ||
| 256 | kvmppc_44x_tlbie(stlb_index); | ||
| 257 | |||
| 258 | /* Now release the page. */ | ||
| 259 | if (ref->writeable) | ||
| 260 | kvm_release_page_dirty(ref->page); | ||
| 261 | else | ||
| 262 | kvm_release_page_clean(ref->page); | ||
| 263 | |||
| 264 | ref->page = NULL; | ||
| 265 | |||
| 266 | /* XXX set tlb_44x_index to stlb_index? */ | ||
| 267 | |||
| 268 | trace_kvm_stlb_inval(stlb_index); | ||
| 269 | } | ||
| 270 | |||
| 271 | void kvmppc_mmu_destroy_44x(struct kvm_vcpu *vcpu) | ||
| 272 | { | ||
| 273 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
| 274 | int i; | ||
| 275 | |||
| 276 | for (i = 0; i <= tlb_44x_hwater; i++) | ||
| 277 | kvmppc_44x_shadow_release(vcpu_44x, i); | ||
| 278 | } | ||
| 279 | |||
| 280 | /** | ||
| 281 | * kvmppc_mmu_map -- create a host mapping for guest memory | ||
| 282 | * | ||
| 283 | * If the guest wanted a larger page than the host supports, only the first | ||
| 284 | * host page is mapped here and the rest are demand faulted. | ||
| 285 | * | ||
| 286 | * If the guest wanted a smaller page than the host page size, we map only the | ||
| 287 | * guest-size page (i.e. not a full host page mapping). | ||
| 288 | * | ||
| 289 | * Caller must ensure that the specified guest TLB entry is safe to insert into | ||
| 290 | * the shadow TLB. | ||
| 291 | */ | ||
| 292 | void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gpa_t gpaddr, | ||
| 293 | unsigned int gtlb_index) | ||
| 294 | { | ||
| 295 | struct kvmppc_44x_tlbe stlbe; | ||
| 296 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
| 297 | struct kvmppc_44x_tlbe *gtlbe = &vcpu_44x->guest_tlb[gtlb_index]; | ||
| 298 | struct kvmppc_44x_shadow_ref *ref; | ||
| 299 | struct page *new_page; | ||
| 300 | hpa_t hpaddr; | ||
| 301 | gfn_t gfn; | ||
| 302 | u32 asid = gtlbe->tid; | ||
| 303 | u32 flags = gtlbe->word2; | ||
| 304 | u32 max_bytes = get_tlb_bytes(gtlbe); | ||
| 305 | unsigned int victim; | ||
| 306 | |||
| 307 | /* Select TLB entry to clobber. Indirectly guard against races with the TLB | ||
| 308 | * miss handler by disabling interrupts. */ | ||
| 309 | local_irq_disable(); | ||
| 310 | victim = ++tlb_44x_index; | ||
| 311 | if (victim > tlb_44x_hwater) | ||
| 312 | victim = 0; | ||
| 313 | tlb_44x_index = victim; | ||
| 314 | local_irq_enable(); | ||
| 315 | |||
| 316 | /* Get reference to new page. */ | ||
| 317 | gfn = gpaddr >> PAGE_SHIFT; | ||
| 318 | new_page = gfn_to_page(vcpu->kvm, gfn); | ||
| 319 | if (is_error_page(new_page)) { | ||
| 320 | printk(KERN_ERR "Couldn't get guest page for gfn %llx!\n", | ||
| 321 | (unsigned long long)gfn); | ||
| 322 | return; | ||
| 323 | } | ||
| 324 | hpaddr = page_to_phys(new_page); | ||
| 325 | |||
| 326 | /* Invalidate any previous shadow mappings. */ | ||
| 327 | kvmppc_44x_shadow_release(vcpu_44x, victim); | ||
| 328 | |||
| 329 | /* XXX Make sure (va, size) doesn't overlap any other | ||
| 330 | * entries. 440x6 user manual says the result would be | ||
| 331 | * "undefined." */ | ||
| 332 | |||
| 333 | /* XXX what about AS? */ | ||
| 334 | |||
| 335 | /* Force TS=1 for all guest mappings. */ | ||
| 336 | stlbe.word0 = PPC44x_TLB_VALID | PPC44x_TLB_TS; | ||
| 337 | |||
| 338 | if (max_bytes >= PAGE_SIZE) { | ||
| 339 | /* Guest mapping is larger than or equal to host page size. We can use | ||
| 340 | * a "native" host mapping. */ | ||
| 341 | stlbe.word0 |= (gvaddr & PAGE_MASK) | PPC44x_TLBE_SIZE; | ||
| 342 | } else { | ||
| 343 | /* Guest mapping is smaller than host page size. We must restrict the | ||
| 344 | * size of the mapping to be at most the smaller of the two, but for | ||
| 345 | * simplicity we fall back to a 4K mapping (this is probably what the | ||
| 346 | * guest is using anyways). */ | ||
| 347 | stlbe.word0 |= (gvaddr & PAGE_MASK_4K) | PPC44x_TLB_4K; | ||
| 348 | |||
| 349 | /* 'hpaddr' is a host page, which is larger than the mapping we're | ||
| 350 | * inserting here. To compensate, we must add the in-page offset to the | ||
| 351 | * sub-page. */ | ||
| 352 | hpaddr |= gpaddr & (PAGE_MASK ^ PAGE_MASK_4K); | ||
| 353 | } | ||
| 354 | |||
| 355 | stlbe.word1 = (hpaddr & 0xfffffc00) | ((hpaddr >> 32) & 0xf); | ||
| 356 | stlbe.word2 = kvmppc_44x_tlb_shadow_attrib(flags, | ||
| 357 | vcpu->arch.shared->msr & MSR_PR); | ||
| 358 | stlbe.tid = !(asid & 0xff); | ||
| 359 | |||
| 360 | /* Keep track of the reference so we can properly release it later. */ | ||
| 361 | ref = &vcpu_44x->shadow_refs[victim]; | ||
| 362 | ref->page = new_page; | ||
| 363 | ref->gtlb_index = gtlb_index; | ||
| 364 | ref->writeable = !!(stlbe.word2 & PPC44x_TLB_UW); | ||
| 365 | ref->tid = stlbe.tid; | ||
| 366 | |||
| 367 | /* Insert shadow mapping into hardware TLB. */ | ||
| 368 | kvmppc_44x_tlbe_set_modified(vcpu_44x, victim); | ||
| 369 | kvmppc_44x_tlbwe(victim, &stlbe); | ||
| 370 | trace_kvm_stlb_write(victim, stlbe.tid, stlbe.word0, stlbe.word1, | ||
| 371 | stlbe.word2); | ||
| 372 | } | ||
| 373 | |||
| 374 | /* For a particular guest TLB entry, invalidate the corresponding host TLB | ||
| 375 | * mappings and release the host pages. */ | ||
| 376 | static void kvmppc_44x_invalidate(struct kvm_vcpu *vcpu, | ||
| 377 | unsigned int gtlb_index) | ||
| 378 | { | ||
| 379 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
| 380 | int i; | ||
| 381 | |||
| 382 | for (i = 0; i < ARRAY_SIZE(vcpu_44x->shadow_refs); i++) { | ||
| 383 | struct kvmppc_44x_shadow_ref *ref = &vcpu_44x->shadow_refs[i]; | ||
| 384 | if (ref->gtlb_index == gtlb_index) | ||
| 385 | kvmppc_44x_shadow_release(vcpu_44x, i); | ||
| 386 | } | ||
| 387 | } | ||
| 388 | |||
| 389 | void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr) | ||
| 390 | { | ||
| 391 | int usermode = vcpu->arch.shared->msr & MSR_PR; | ||
| 392 | |||
| 393 | vcpu->arch.shadow_pid = !usermode; | ||
| 394 | } | ||
| 395 | |||
| 396 | void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 new_pid) | ||
| 397 | { | ||
| 398 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
| 399 | int i; | ||
| 400 | |||
| 401 | if (unlikely(vcpu->arch.pid == new_pid)) | ||
| 402 | return; | ||
| 403 | |||
| 404 | vcpu->arch.pid = new_pid; | ||
| 405 | |||
| 406 | /* Guest userspace runs with TID=0 mappings and PID=0, to make sure it | ||
| 407 | * can't access guest kernel mappings (TID=1). When we switch to a new | ||
| 408 | * guest PID, which will also use host PID=0, we must discard the old guest | ||
| 409 | * userspace mappings. */ | ||
| 410 | for (i = 0; i < ARRAY_SIZE(vcpu_44x->shadow_refs); i++) { | ||
| 411 | struct kvmppc_44x_shadow_ref *ref = &vcpu_44x->shadow_refs[i]; | ||
| 412 | |||
| 413 | if (ref->tid == 0) | ||
| 414 | kvmppc_44x_shadow_release(vcpu_44x, i); | ||
| 415 | } | ||
| 416 | } | ||
| 417 | |||
| 418 | static int tlbe_is_host_safe(const struct kvm_vcpu *vcpu, | ||
| 419 | const struct kvmppc_44x_tlbe *tlbe) | ||
| 420 | { | ||
| 421 | gpa_t gpa; | ||
| 422 | |||
| 423 | if (!get_tlb_v(tlbe)) | ||
| 424 | return 0; | ||
| 425 | |||
| 426 | /* Does it match current guest AS? */ | ||
| 427 | /* XXX what about IS != DS? */ | ||
| 428 | if (get_tlb_ts(tlbe) != !!(vcpu->arch.shared->msr & MSR_IS)) | ||
| 429 | return 0; | ||
| 430 | |||
| 431 | gpa = get_tlb_raddr(tlbe); | ||
| 432 | if (!gfn_to_memslot(vcpu->kvm, gpa >> PAGE_SHIFT)) | ||
| 433 | /* Mapping is not for RAM. */ | ||
| 434 | return 0; | ||
| 435 | |||
| 436 | return 1; | ||
| 437 | } | ||
| 438 | |||
| 439 | int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws) | ||
| 440 | { | ||
| 441 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
| 442 | struct kvmppc_44x_tlbe *tlbe; | ||
| 443 | unsigned int gtlb_index; | ||
| 444 | int idx; | ||
| 445 | |||
| 446 | gtlb_index = kvmppc_get_gpr(vcpu, ra); | ||
| 447 | if (gtlb_index >= KVM44x_GUEST_TLB_SIZE) { | ||
| 448 | printk("%s: index %d\n", __func__, gtlb_index); | ||
| 449 | kvmppc_dump_vcpu(vcpu); | ||
| 450 | return EMULATE_FAIL; | ||
| 451 | } | ||
| 452 | |||
| 453 | tlbe = &vcpu_44x->guest_tlb[gtlb_index]; | ||
| 454 | |||
| 455 | /* Invalidate shadow mappings for the about-to-be-clobbered TLB entry. */ | ||
| 456 | if (tlbe->word0 & PPC44x_TLB_VALID) | ||
| 457 | kvmppc_44x_invalidate(vcpu, gtlb_index); | ||
| 458 | |||
| 459 | switch (ws) { | ||
| 460 | case PPC44x_TLB_PAGEID: | ||
| 461 | tlbe->tid = get_mmucr_stid(vcpu); | ||
| 462 | tlbe->word0 = kvmppc_get_gpr(vcpu, rs); | ||
| 463 | break; | ||
| 464 | |||
| 465 | case PPC44x_TLB_XLAT: | ||
| 466 | tlbe->word1 = kvmppc_get_gpr(vcpu, rs); | ||
| 467 | break; | ||
| 468 | |||
| 469 | case PPC44x_TLB_ATTRIB: | ||
| 470 | tlbe->word2 = kvmppc_get_gpr(vcpu, rs); | ||
| 471 | break; | ||
| 472 | |||
| 473 | default: | ||
| 474 | return EMULATE_FAIL; | ||
| 475 | } | ||
| 476 | |||
| 477 | idx = srcu_read_lock(&vcpu->kvm->srcu); | ||
| 478 | |||
| 479 | if (tlbe_is_host_safe(vcpu, tlbe)) { | ||
| 480 | gva_t eaddr; | ||
| 481 | gpa_t gpaddr; | ||
| 482 | u32 bytes; | ||
| 483 | |||
| 484 | eaddr = get_tlb_eaddr(tlbe); | ||
| 485 | gpaddr = get_tlb_raddr(tlbe); | ||
| 486 | |||
| 487 | /* Use the advertised page size to mask effective and real addrs. */ | ||
| 488 | bytes = get_tlb_bytes(tlbe); | ||
| 489 | eaddr &= ~(bytes - 1); | ||
| 490 | gpaddr &= ~(bytes - 1); | ||
| 491 | |||
| 492 | kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index); | ||
| 493 | } | ||
| 494 | |||
| 495 | srcu_read_unlock(&vcpu->kvm->srcu, idx); | ||
| 496 | |||
| 497 | trace_kvm_gtlb_write(gtlb_index, tlbe->tid, tlbe->word0, tlbe->word1, | ||
| 498 | tlbe->word2); | ||
| 499 | |||
| 500 | kvmppc_set_exit_type(vcpu, EMULATED_TLBWE_EXITS); | ||
| 501 | return EMULATE_DONE; | ||
| 502 | } | ||
| 503 | |||
| 504 | int kvmppc_44x_emul_tlbsx(struct kvm_vcpu *vcpu, u8 rt, u8 ra, u8 rb, u8 rc) | ||
| 505 | { | ||
| 506 | u32 ea; | ||
| 507 | int gtlb_index; | ||
| 508 | unsigned int as = get_mmucr_sts(vcpu); | ||
| 509 | unsigned int pid = get_mmucr_stid(vcpu); | ||
| 510 | |||
| 511 | ea = kvmppc_get_gpr(vcpu, rb); | ||
| 512 | if (ra) | ||
| 513 | ea += kvmppc_get_gpr(vcpu, ra); | ||
| 514 | |||
| 515 | gtlb_index = kvmppc_44x_tlb_index(vcpu, ea, pid, as); | ||
| 516 | if (rc) { | ||
| 517 | u32 cr = kvmppc_get_cr(vcpu); | ||
| 518 | |||
| 519 | if (gtlb_index < 0) | ||
| 520 | kvmppc_set_cr(vcpu, cr & ~0x20000000); | ||
| 521 | else | ||
| 522 | kvmppc_set_cr(vcpu, cr | 0x20000000); | ||
| 523 | } | ||
| 524 | kvmppc_set_gpr(vcpu, rt, gtlb_index); | ||
| 525 | |||
| 526 | kvmppc_set_exit_type(vcpu, EMULATED_TLBSX_EXITS); | ||
| 527 | return EMULATE_DONE; | ||
| 528 | } | ||
diff --git a/arch/powerpc/kvm/44x_tlb.h b/arch/powerpc/kvm/44x_tlb.h deleted file mode 100644 index a9ff80e51526..000000000000 --- a/arch/powerpc/kvm/44x_tlb.h +++ /dev/null | |||
| @@ -1,86 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify | ||
| 3 | * it under the terms of the GNU General Public License, version 2, as | ||
| 4 | * published by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * This program is distributed in the hope that it will be useful, | ||
| 7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 9 | * GNU General Public License for more details. | ||
| 10 | * | ||
| 11 | * You should have received a copy of the GNU General Public License | ||
| 12 | * along with this program; if not, write to the Free Software | ||
| 13 | * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 14 | * | ||
| 15 | * Copyright IBM Corp. 2007 | ||
| 16 | * | ||
| 17 | * Authors: Hollis Blanchard <hollisb@us.ibm.com> | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef __KVM_POWERPC_TLB_H__ | ||
| 21 | #define __KVM_POWERPC_TLB_H__ | ||
| 22 | |||
| 23 | #include <linux/kvm_host.h> | ||
| 24 | #include <asm/mmu-44x.h> | ||
| 25 | |||
| 26 | extern int kvmppc_44x_tlb_index(struct kvm_vcpu *vcpu, gva_t eaddr, | ||
| 27 | unsigned int pid, unsigned int as); | ||
| 28 | |||
| 29 | extern int kvmppc_44x_emul_tlbsx(struct kvm_vcpu *vcpu, u8 rt, u8 ra, u8 rb, | ||
| 30 | u8 rc); | ||
| 31 | extern int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws); | ||
| 32 | |||
| 33 | /* TLB helper functions */ | ||
| 34 | static inline unsigned int get_tlb_size(const struct kvmppc_44x_tlbe *tlbe) | ||
| 35 | { | ||
| 36 | return (tlbe->word0 >> 4) & 0xf; | ||
| 37 | } | ||
| 38 | |||
| 39 | static inline gva_t get_tlb_eaddr(const struct kvmppc_44x_tlbe *tlbe) | ||
| 40 | { | ||
| 41 | return tlbe->word0 & 0xfffffc00; | ||
| 42 | } | ||
| 43 | |||
| 44 | static inline gva_t get_tlb_bytes(const struct kvmppc_44x_tlbe *tlbe) | ||
| 45 | { | ||
| 46 | unsigned int pgsize = get_tlb_size(tlbe); | ||
| 47 | return 1 << 10 << (pgsize << 1); | ||
| 48 | } | ||
| 49 | |||
| 50 | static inline gva_t get_tlb_end(const struct kvmppc_44x_tlbe *tlbe) | ||
| 51 | { | ||
| 52 | return get_tlb_eaddr(tlbe) + get_tlb_bytes(tlbe) - 1; | ||
| 53 | } | ||
| 54 | |||
| 55 | static inline u64 get_tlb_raddr(const struct kvmppc_44x_tlbe *tlbe) | ||
| 56 | { | ||
| 57 | u64 word1 = tlbe->word1; | ||
| 58 | return ((word1 & 0xf) << 32) | (word1 & 0xfffffc00); | ||
| 59 | } | ||
| 60 | |||
| 61 | static inline unsigned int get_tlb_tid(const struct kvmppc_44x_tlbe *tlbe) | ||
| 62 | { | ||
| 63 | return tlbe->tid & 0xff; | ||
| 64 | } | ||
| 65 | |||
| 66 | static inline unsigned int get_tlb_ts(const struct kvmppc_44x_tlbe *tlbe) | ||
| 67 | { | ||
| 68 | return (tlbe->word0 >> 8) & 0x1; | ||
| 69 | } | ||
| 70 | |||
| 71 | static inline unsigned int get_tlb_v(const struct kvmppc_44x_tlbe *tlbe) | ||
| 72 | { | ||
| 73 | return (tlbe->word0 >> 9) & 0x1; | ||
| 74 | } | ||
| 75 | |||
| 76 | static inline unsigned int get_mmucr_stid(const struct kvm_vcpu *vcpu) | ||
| 77 | { | ||
| 78 | return vcpu->arch.mmucr & 0xff; | ||
| 79 | } | ||
| 80 | |||
| 81 | static inline unsigned int get_mmucr_sts(const struct kvm_vcpu *vcpu) | ||
| 82 | { | ||
| 83 | return (vcpu->arch.mmucr >> 16) & 0x1; | ||
| 84 | } | ||
| 85 | |||
| 86 | #endif /* __KVM_POWERPC_TLB_H__ */ | ||
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index d6a53b95de94..602eb51d20bc 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig | |||
| @@ -75,7 +75,6 @@ config KVM_BOOK3S_64 | |||
| 75 | config KVM_BOOK3S_64_HV | 75 | config KVM_BOOK3S_64_HV |
| 76 | tristate "KVM support for POWER7 and PPC970 using hypervisor mode in host" | 76 | tristate "KVM support for POWER7 and PPC970 using hypervisor mode in host" |
| 77 | depends on KVM_BOOK3S_64 | 77 | depends on KVM_BOOK3S_64 |
| 78 | depends on !CPU_LITTLE_ENDIAN | ||
| 79 | select KVM_BOOK3S_HV_POSSIBLE | 78 | select KVM_BOOK3S_HV_POSSIBLE |
| 80 | select MMU_NOTIFIER | 79 | select MMU_NOTIFIER |
| 81 | select CMA | 80 | select CMA |
| @@ -113,23 +112,9 @@ config KVM_BOOK3S_64_PR | |||
| 113 | config KVM_BOOKE_HV | 112 | config KVM_BOOKE_HV |
| 114 | bool | 113 | bool |
| 115 | 114 | ||
| 116 | config KVM_440 | ||
| 117 | bool "KVM support for PowerPC 440 processors" | ||
| 118 | depends on 44x | ||
| 119 | select KVM | ||
| 120 | select KVM_MMIO | ||
| 121 | ---help--- | ||
| 122 | Support running unmodified 440 guest kernels in virtual machines on | ||
| 123 | 440 host processors. | ||
| 124 | |||
| 125 | This module provides access to the hardware capabilities through | ||
| 126 | a character device node named /dev/kvm. | ||
| 127 | |||
| 128 | If unsure, say N. | ||
| 129 | |||
| 130 | config KVM_EXIT_TIMING | 115 | config KVM_EXIT_TIMING |
| 131 | bool "Detailed exit timing" | 116 | bool "Detailed exit timing" |
| 132 | depends on KVM_440 || KVM_E500V2 || KVM_E500MC | 117 | depends on KVM_E500V2 || KVM_E500MC |
| 133 | ---help--- | 118 | ---help--- |
| 134 | Calculate elapsed time for every exit/enter cycle. A per-vcpu | 119 | Calculate elapsed time for every exit/enter cycle. A per-vcpu |
| 135 | report is available in debugfs kvm/vm#_vcpu#_timing. | 120 | report is available in debugfs kvm/vm#_vcpu#_timing. |
| @@ -173,6 +158,7 @@ config KVM_MPIC | |||
| 173 | bool "KVM in-kernel MPIC emulation" | 158 | bool "KVM in-kernel MPIC emulation" |
| 174 | depends on KVM && E500 | 159 | depends on KVM && E500 |
| 175 | select HAVE_KVM_IRQCHIP | 160 | select HAVE_KVM_IRQCHIP |
| 161 | select HAVE_KVM_IRQFD | ||
| 176 | select HAVE_KVM_IRQ_ROUTING | 162 | select HAVE_KVM_IRQ_ROUTING |
| 177 | select HAVE_KVM_MSI | 163 | select HAVE_KVM_MSI |
| 178 | help | 164 | help |
| @@ -184,6 +170,8 @@ config KVM_MPIC | |||
| 184 | config KVM_XICS | 170 | config KVM_XICS |
| 185 | bool "KVM in-kernel XICS emulation" | 171 | bool "KVM in-kernel XICS emulation" |
| 186 | depends on KVM_BOOK3S_64 && !KVM_MPIC | 172 | depends on KVM_BOOK3S_64 && !KVM_MPIC |
| 173 | select HAVE_KVM_IRQCHIP | ||
| 174 | select HAVE_KVM_IRQFD | ||
| 187 | ---help--- | 175 | ---help--- |
| 188 | Include support for the XICS (eXternal Interrupt Controller | 176 | Include support for the XICS (eXternal Interrupt Controller |
| 189 | Specification) interrupt controller architecture used on | 177 | Specification) interrupt controller architecture used on |
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 72905c30082e..0570eef83fba 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile | |||
| @@ -10,27 +10,17 @@ KVM := ../../../virt/kvm | |||
| 10 | common-objs-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \ | 10 | common-objs-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \ |
| 11 | $(KVM)/eventfd.o | 11 | $(KVM)/eventfd.o |
| 12 | 12 | ||
| 13 | CFLAGS_44x_tlb.o := -I. | ||
| 14 | CFLAGS_e500_mmu.o := -I. | 13 | CFLAGS_e500_mmu.o := -I. |
| 15 | CFLAGS_e500_mmu_host.o := -I. | 14 | CFLAGS_e500_mmu_host.o := -I. |
| 16 | CFLAGS_emulate.o := -I. | 15 | CFLAGS_emulate.o := -I. |
| 16 | CFLAGS_emulate_loadstore.o := -I. | ||
| 17 | 17 | ||
| 18 | common-objs-y += powerpc.o emulate.o | 18 | common-objs-y += powerpc.o emulate.o emulate_loadstore.o |
| 19 | obj-$(CONFIG_KVM_EXIT_TIMING) += timing.o | 19 | obj-$(CONFIG_KVM_EXIT_TIMING) += timing.o |
| 20 | obj-$(CONFIG_KVM_BOOK3S_HANDLER) += book3s_exports.o | 20 | obj-$(CONFIG_KVM_BOOK3S_HANDLER) += book3s_exports.o |
| 21 | 21 | ||
| 22 | AFLAGS_booke_interrupts.o := -I$(obj) | 22 | AFLAGS_booke_interrupts.o := -I$(obj) |
| 23 | 23 | ||
| 24 | kvm-440-objs := \ | ||
| 25 | $(common-objs-y) \ | ||
| 26 | booke.o \ | ||
| 27 | booke_emulate.o \ | ||
| 28 | booke_interrupts.o \ | ||
| 29 | 44x.o \ | ||
| 30 | 44x_tlb.o \ | ||
| 31 | 44x_emulate.o | ||
| 32 | kvm-objs-$(CONFIG_KVM_440) := $(kvm-440-objs) | ||
| 33 | |||
| 34 | kvm-e500-objs := \ | 24 | kvm-e500-objs := \ |
| 35 | $(common-objs-y) \ | 25 | $(common-objs-y) \ |
| 36 | booke.o \ | 26 | booke.o \ |
| @@ -58,6 +48,7 @@ kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_HANDLER) := \ | |||
| 58 | 48 | ||
| 59 | kvm-pr-y := \ | 49 | kvm-pr-y := \ |
| 60 | fpu.o \ | 50 | fpu.o \ |
| 51 | emulate.o \ | ||
| 61 | book3s_paired_singles.o \ | 52 | book3s_paired_singles.o \ |
| 62 | book3s_pr.o \ | 53 | book3s_pr.o \ |
| 63 | book3s_pr_papr.o \ | 54 | book3s_pr_papr.o \ |
| @@ -100,7 +91,7 @@ kvm-book3s_64-module-objs += \ | |||
| 100 | $(KVM)/kvm_main.o \ | 91 | $(KVM)/kvm_main.o \ |
| 101 | $(KVM)/eventfd.o \ | 92 | $(KVM)/eventfd.o \ |
| 102 | powerpc.o \ | 93 | powerpc.o \ |
| 103 | emulate.o \ | 94 | emulate_loadstore.o \ |
| 104 | book3s.o \ | 95 | book3s.o \ |
| 105 | book3s_64_vio.o \ | 96 | book3s_64_vio.o \ |
| 106 | book3s_rtas.o \ | 97 | book3s_rtas.o \ |
| @@ -126,7 +117,6 @@ kvm-objs-$(CONFIG_HAVE_KVM_IRQ_ROUTING) += $(KVM)/irqchip.o | |||
| 126 | 117 | ||
| 127 | kvm-objs := $(kvm-objs-m) $(kvm-objs-y) | 118 | kvm-objs := $(kvm-objs-m) $(kvm-objs-y) |
| 128 | 119 | ||
| 129 | obj-$(CONFIG_KVM_440) += kvm.o | ||
| 130 | obj-$(CONFIG_KVM_E500V2) += kvm.o | 120 | obj-$(CONFIG_KVM_E500V2) += kvm.o |
| 131 | obj-$(CONFIG_KVM_E500MC) += kvm.o | 121 | obj-$(CONFIG_KVM_E500MC) += kvm.o |
| 132 | obj-$(CONFIG_KVM_BOOK3S_64) += kvm.o | 122 | obj-$(CONFIG_KVM_BOOK3S_64) += kvm.o |
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index c254c27f240e..dd03f6b299ba 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c | |||
| @@ -72,6 +72,17 @@ void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu) | |||
| 72 | { | 72 | { |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | void kvmppc_unfixup_split_real(struct kvm_vcpu *vcpu) | ||
| 76 | { | ||
| 77 | if (vcpu->arch.hflags & BOOK3S_HFLAG_SPLIT_HACK) { | ||
| 78 | ulong pc = kvmppc_get_pc(vcpu); | ||
| 79 | if ((pc & SPLIT_HACK_MASK) == SPLIT_HACK_OFFS) | ||
| 80 | kvmppc_set_pc(vcpu, pc & ~SPLIT_HACK_MASK); | ||
| 81 | vcpu->arch.hflags &= ~BOOK3S_HFLAG_SPLIT_HACK; | ||
| 82 | } | ||
| 83 | } | ||
| 84 | EXPORT_SYMBOL_GPL(kvmppc_unfixup_split_real); | ||
| 85 | |||
| 75 | static inline unsigned long kvmppc_interrupt_offset(struct kvm_vcpu *vcpu) | 86 | static inline unsigned long kvmppc_interrupt_offset(struct kvm_vcpu *vcpu) |
| 76 | { | 87 | { |
| 77 | if (!is_kvmppc_hv_enabled(vcpu->kvm)) | 88 | if (!is_kvmppc_hv_enabled(vcpu->kvm)) |
| @@ -118,6 +129,7 @@ static inline bool kvmppc_critical_section(struct kvm_vcpu *vcpu) | |||
| 118 | 129 | ||
| 119 | void kvmppc_inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 flags) | 130 | void kvmppc_inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 flags) |
| 120 | { | 131 | { |
| 132 | kvmppc_unfixup_split_real(vcpu); | ||
| 121 | kvmppc_set_srr0(vcpu, kvmppc_get_pc(vcpu)); | 133 | kvmppc_set_srr0(vcpu, kvmppc_get_pc(vcpu)); |
| 122 | kvmppc_set_srr1(vcpu, kvmppc_get_msr(vcpu) | flags); | 134 | kvmppc_set_srr1(vcpu, kvmppc_get_msr(vcpu) | flags); |
| 123 | kvmppc_set_pc(vcpu, kvmppc_interrupt_offset(vcpu) + vec); | 135 | kvmppc_set_pc(vcpu, kvmppc_interrupt_offset(vcpu) + vec); |
| @@ -218,6 +230,23 @@ void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu) | |||
| 218 | kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL_LEVEL); | 230 | kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL_LEVEL); |
| 219 | } | 231 | } |
| 220 | 232 | ||
| 233 | void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu, ulong dar, | ||
| 234 | ulong flags) | ||
| 235 | { | ||
| 236 | kvmppc_set_dar(vcpu, dar); | ||
| 237 | kvmppc_set_dsisr(vcpu, flags); | ||
| 238 | kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_DATA_STORAGE); | ||
| 239 | } | ||
| 240 | |||
| 241 | void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu, ulong flags) | ||
| 242 | { | ||
| 243 | u64 msr = kvmppc_get_msr(vcpu); | ||
| 244 | msr &= ~(SRR1_ISI_NOPT | SRR1_ISI_N_OR_G | SRR1_ISI_PROT); | ||
| 245 | msr |= flags & (SRR1_ISI_NOPT | SRR1_ISI_N_OR_G | SRR1_ISI_PROT); | ||
| 246 | kvmppc_set_msr_fast(vcpu, msr); | ||
| 247 | kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_INST_STORAGE); | ||
| 248 | } | ||
| 249 | |||
| 221 | int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority) | 250 | int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority) |
| 222 | { | 251 | { |
| 223 | int deliver = 1; | 252 | int deliver = 1; |
| @@ -342,18 +371,18 @@ int kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu) | |||
| 342 | } | 371 | } |
| 343 | EXPORT_SYMBOL_GPL(kvmppc_core_prepare_to_enter); | 372 | EXPORT_SYMBOL_GPL(kvmppc_core_prepare_to_enter); |
| 344 | 373 | ||
| 345 | pfn_t kvmppc_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn, bool writing, | 374 | pfn_t kvmppc_gpa_to_pfn(struct kvm_vcpu *vcpu, gpa_t gpa, bool writing, |
| 346 | bool *writable) | 375 | bool *writable) |
| 347 | { | 376 | { |
| 348 | ulong mp_pa = vcpu->arch.magic_page_pa; | 377 | ulong mp_pa = vcpu->arch.magic_page_pa & KVM_PAM; |
| 378 | gfn_t gfn = gpa >> PAGE_SHIFT; | ||
| 349 | 379 | ||
| 350 | if (!(kvmppc_get_msr(vcpu) & MSR_SF)) | 380 | if (!(kvmppc_get_msr(vcpu) & MSR_SF)) |
| 351 | mp_pa = (uint32_t)mp_pa; | 381 | mp_pa = (uint32_t)mp_pa; |
| 352 | 382 | ||
| 353 | /* Magic page override */ | 383 | /* Magic page override */ |
| 354 | if (unlikely(mp_pa) && | 384 | gpa &= ~0xFFFULL; |
| 355 | unlikely(((gfn << PAGE_SHIFT) & KVM_PAM) == | 385 | if (unlikely(mp_pa) && unlikely((gpa & KVM_PAM) == mp_pa)) { |
| 356 | ((mp_pa & PAGE_MASK) & KVM_PAM))) { | ||
| 357 | ulong shared_page = ((ulong)vcpu->arch.shared) & PAGE_MASK; | 386 | ulong shared_page = ((ulong)vcpu->arch.shared) & PAGE_MASK; |
| 358 | pfn_t pfn; | 387 | pfn_t pfn; |
| 359 | 388 | ||
| @@ -366,11 +395,13 @@ pfn_t kvmppc_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn, bool writing, | |||
| 366 | 395 | ||
| 367 | return gfn_to_pfn_prot(vcpu->kvm, gfn, writing, writable); | 396 | return gfn_to_pfn_prot(vcpu->kvm, gfn, writing, writable); |
| 368 | } | 397 | } |
| 369 | EXPORT_SYMBOL_GPL(kvmppc_gfn_to_pfn); | 398 | EXPORT_SYMBOL_GPL(kvmppc_gpa_to_pfn); |
| 370 | 399 | ||
| 371 | static int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, bool data, | 400 | int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, enum xlate_instdata xlid, |
| 372 | bool iswrite, struct kvmppc_pte *pte) | 401 | enum xlate_readwrite xlrw, struct kvmppc_pte *pte) |
| 373 | { | 402 | { |
| 403 | bool data = (xlid == XLATE_DATA); | ||
| 404 | bool iswrite = (xlrw == XLATE_WRITE); | ||
| 374 | int relocated = (kvmppc_get_msr(vcpu) & (data ? MSR_DR : MSR_IR)); | 405 | int relocated = (kvmppc_get_msr(vcpu) & (data ? MSR_DR : MSR_IR)); |
| 375 | int r; | 406 | int r; |
| 376 | 407 | ||
| @@ -384,88 +415,34 @@ static int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, bool data, | |||
| 384 | pte->may_write = true; | 415 | pte->may_write = true; |
| 385 | pte->may_execute = true; | 416 | pte->may_execute = true; |
| 386 | r = 0; | 417 | r = 0; |
| 418 | |||
| 419 | if ((kvmppc_get_msr(vcpu) & (MSR_IR | MSR_DR)) == MSR_DR && | ||
| 420 | !data) { | ||
| 421 | if ((vcpu->arch.hflags & BOOK3S_HFLAG_SPLIT_HACK) && | ||
| 422 | ((eaddr & SPLIT_HACK_MASK) == SPLIT_HACK_OFFS)) | ||
| 423 | pte->raddr &= ~SPLIT_HACK_MASK; | ||
| 424 | } | ||
| 387 | } | 425 | } |
| 388 | 426 | ||
| 389 | return r; | 427 | return r; |
| 390 | } | 428 | } |
| 391 | 429 | ||
| 392 | static hva_t kvmppc_bad_hva(void) | 430 | int kvmppc_load_last_inst(struct kvm_vcpu *vcpu, enum instruction_type type, |
| 393 | { | 431 | u32 *inst) |
| 394 | return PAGE_OFFSET; | ||
| 395 | } | ||
| 396 | |||
| 397 | static hva_t kvmppc_pte_to_hva(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte, | ||
| 398 | bool read) | ||
| 399 | { | ||
| 400 | hva_t hpage; | ||
| 401 | |||
| 402 | if (read && !pte->may_read) | ||
| 403 | goto err; | ||
| 404 | |||
| 405 | if (!read && !pte->may_write) | ||
| 406 | goto err; | ||
| 407 | |||
| 408 | hpage = gfn_to_hva(vcpu->kvm, pte->raddr >> PAGE_SHIFT); | ||
| 409 | if (kvm_is_error_hva(hpage)) | ||
| 410 | goto err; | ||
| 411 | |||
| 412 | return hpage | (pte->raddr & ~PAGE_MASK); | ||
| 413 | err: | ||
| 414 | return kvmppc_bad_hva(); | ||
| 415 | } | ||
| 416 | |||
| 417 | int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, | ||
| 418 | bool data) | ||
| 419 | { | ||
| 420 | struct kvmppc_pte pte; | ||
| 421 | |||
| 422 | vcpu->stat.st++; | ||
| 423 | |||
| 424 | if (kvmppc_xlate(vcpu, *eaddr, data, true, &pte)) | ||
| 425 | return -ENOENT; | ||
| 426 | |||
| 427 | *eaddr = pte.raddr; | ||
| 428 | |||
| 429 | if (!pte.may_write) | ||
| 430 | return -EPERM; | ||
| 431 | |||
| 432 | if (kvm_write_guest(vcpu->kvm, pte.raddr, ptr, size)) | ||
| 433 | return EMULATE_DO_MMIO; | ||
| 434 | |||
| 435 | return EMULATE_DONE; | ||
| 436 | } | ||
| 437 | EXPORT_SYMBOL_GPL(kvmppc_st); | ||
| 438 | |||
| 439 | int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, | ||
| 440 | bool data) | ||
| 441 | { | 432 | { |
| 442 | struct kvmppc_pte pte; | 433 | ulong pc = kvmppc_get_pc(vcpu); |
| 443 | hva_t hva = *eaddr; | 434 | int r; |
| 444 | |||
| 445 | vcpu->stat.ld++; | ||
| 446 | |||
| 447 | if (kvmppc_xlate(vcpu, *eaddr, data, false, &pte)) | ||
| 448 | goto nopte; | ||
| 449 | |||
| 450 | *eaddr = pte.raddr; | ||
| 451 | |||
| 452 | hva = kvmppc_pte_to_hva(vcpu, &pte, true); | ||
| 453 | if (kvm_is_error_hva(hva)) | ||
| 454 | goto mmio; | ||
| 455 | |||
| 456 | if (copy_from_user(ptr, (void __user *)hva, size)) { | ||
| 457 | printk(KERN_INFO "kvmppc_ld at 0x%lx failed\n", hva); | ||
| 458 | goto mmio; | ||
| 459 | } | ||
| 460 | 435 | ||
| 461 | return EMULATE_DONE; | 436 | if (type == INST_SC) |
| 437 | pc -= 4; | ||
| 462 | 438 | ||
| 463 | nopte: | 439 | r = kvmppc_ld(vcpu, &pc, sizeof(u32), inst, false); |
| 464 | return -ENOENT; | 440 | if (r == EMULATE_DONE) |
| 465 | mmio: | 441 | return r; |
| 466 | return EMULATE_DO_MMIO; | 442 | else |
| 443 | return EMULATE_AGAIN; | ||
| 467 | } | 444 | } |
| 468 | EXPORT_SYMBOL_GPL(kvmppc_ld); | 445 | EXPORT_SYMBOL_GPL(kvmppc_load_last_inst); |
| 469 | 446 | ||
| 470 | int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | 447 | int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) |
| 471 | { | 448 | { |
| @@ -646,6 +623,12 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) | |||
| 646 | case KVM_REG_PPC_BESCR: | 623 | case KVM_REG_PPC_BESCR: |
| 647 | val = get_reg_val(reg->id, vcpu->arch.bescr); | 624 | val = get_reg_val(reg->id, vcpu->arch.bescr); |
| 648 | break; | 625 | break; |
| 626 | case KVM_REG_PPC_VTB: | ||
| 627 | val = get_reg_val(reg->id, vcpu->arch.vtb); | ||
| 628 | break; | ||
| 629 | case KVM_REG_PPC_IC: | ||
| 630 | val = get_reg_val(reg->id, vcpu->arch.ic); | ||
| 631 | break; | ||
| 649 | default: | 632 | default: |
| 650 | r = -EINVAL; | 633 | r = -EINVAL; |
| 651 | break; | 634 | break; |
| @@ -750,6 +733,12 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) | |||
| 750 | case KVM_REG_PPC_BESCR: | 733 | case KVM_REG_PPC_BESCR: |
| 751 | vcpu->arch.bescr = set_reg_val(reg->id, val); | 734 | vcpu->arch.bescr = set_reg_val(reg->id, val); |
| 752 | break; | 735 | break; |
| 736 | case KVM_REG_PPC_VTB: | ||
| 737 | vcpu->arch.vtb = set_reg_val(reg->id, val); | ||
| 738 | break; | ||
| 739 | case KVM_REG_PPC_IC: | ||
| 740 | vcpu->arch.ic = set_reg_val(reg->id, val); | ||
| 741 | break; | ||
| 753 | default: | 742 | default: |
| 754 | r = -EINVAL; | 743 | r = -EINVAL; |
| 755 | break; | 744 | break; |
| @@ -913,6 +902,11 @@ int kvmppc_core_check_processor_compat(void) | |||
| 913 | return 0; | 902 | return 0; |
| 914 | } | 903 | } |
| 915 | 904 | ||
| 905 | int kvmppc_book3s_hcall_implemented(struct kvm *kvm, unsigned long hcall) | ||
| 906 | { | ||
| 907 | return kvm->arch.kvm_ops->hcall_implemented(hcall); | ||
| 908 | } | ||
| 909 | |||
| 916 | static int kvmppc_book3s_init(void) | 910 | static int kvmppc_book3s_init(void) |
| 917 | { | 911 | { |
| 918 | int r; | 912 | int r; |
diff --git a/arch/powerpc/kvm/book3s_32_mmu.c b/arch/powerpc/kvm/book3s_32_mmu.c index 93503bbdae43..cd0b0730e29e 100644 --- a/arch/powerpc/kvm/book3s_32_mmu.c +++ b/arch/powerpc/kvm/book3s_32_mmu.c | |||
| @@ -335,7 +335,7 @@ static int kvmppc_mmu_book3s_32_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, | |||
| 335 | if (r < 0) | 335 | if (r < 0) |
| 336 | r = kvmppc_mmu_book3s_32_xlate_pte(vcpu, eaddr, pte, | 336 | r = kvmppc_mmu_book3s_32_xlate_pte(vcpu, eaddr, pte, |
| 337 | data, iswrite, true); | 337 | data, iswrite, true); |
| 338 | if (r < 0) | 338 | if (r == -ENOENT) |
| 339 | r = kvmppc_mmu_book3s_32_xlate_pte(vcpu, eaddr, pte, | 339 | r = kvmppc_mmu_book3s_32_xlate_pte(vcpu, eaddr, pte, |
| 340 | data, iswrite, false); | 340 | data, iswrite, false); |
| 341 | 341 | ||
diff --git a/arch/powerpc/kvm/book3s_32_mmu_host.c b/arch/powerpc/kvm/book3s_32_mmu_host.c index 678e75370495..2035d16a9262 100644 --- a/arch/powerpc/kvm/book3s_32_mmu_host.c +++ b/arch/powerpc/kvm/book3s_32_mmu_host.c | |||
| @@ -156,11 +156,10 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte, | |||
| 156 | bool writable; | 156 | bool writable; |
| 157 | 157 | ||
| 158 | /* Get host physical address for gpa */ | 158 | /* Get host physical address for gpa */ |
| 159 | hpaddr = kvmppc_gfn_to_pfn(vcpu, orig_pte->raddr >> PAGE_SHIFT, | 159 | hpaddr = kvmppc_gpa_to_pfn(vcpu, orig_pte->raddr, iswrite, &writable); |
| 160 | iswrite, &writable); | ||
| 161 | if (is_error_noslot_pfn(hpaddr)) { | 160 | if (is_error_noslot_pfn(hpaddr)) { |
| 162 | printk(KERN_INFO "Couldn't get guest page for gfn %lx!\n", | 161 | printk(KERN_INFO "Couldn't get guest page for gpa %lx!\n", |
| 163 | orig_pte->eaddr); | 162 | orig_pte->raddr); |
| 164 | r = -EINVAL; | 163 | r = -EINVAL; |
| 165 | goto out; | 164 | goto out; |
| 166 | } | 165 | } |
diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c index 0ac98392f363..b982d925c710 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/arch/powerpc/kvm/book3s_64_mmu_host.c | |||
| @@ -104,9 +104,10 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte, | |||
| 104 | smp_rmb(); | 104 | smp_rmb(); |
| 105 | 105 | ||
| 106 | /* Get host physical address for gpa */ | 106 | /* Get host physical address for gpa */ |
| 107 | pfn = kvmppc_gfn_to_pfn(vcpu, gfn, iswrite, &writable); | 107 | pfn = kvmppc_gpa_to_pfn(vcpu, orig_pte->raddr, iswrite, &writable); |
| 108 | if (is_error_noslot_pfn(pfn)) { | 108 | if (is_error_noslot_pfn(pfn)) { |
| 109 | printk(KERN_INFO "Couldn't get guest page for gfn %lx!\n", gfn); | 109 | printk(KERN_INFO "Couldn't get guest page for gpa %lx!\n", |
| 110 | orig_pte->raddr); | ||
| 110 | r = -EINVAL; | 111 | r = -EINVAL; |
| 111 | goto out; | 112 | goto out; |
| 112 | } | 113 | } |
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index a01744fc3483..72c20bb16d26 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c | |||
| @@ -448,7 +448,7 @@ static int kvmppc_mmu_book3s_64_hv_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, | |||
| 448 | unsigned long slb_v; | 448 | unsigned long slb_v; |
| 449 | unsigned long pp, key; | 449 | unsigned long pp, key; |
| 450 | unsigned long v, gr; | 450 | unsigned long v, gr; |
| 451 | unsigned long *hptep; | 451 | __be64 *hptep; |
| 452 | int index; | 452 | int index; |
| 453 | int virtmode = vcpu->arch.shregs.msr & (data ? MSR_DR : MSR_IR); | 453 | int virtmode = vcpu->arch.shregs.msr & (data ? MSR_DR : MSR_IR); |
| 454 | 454 | ||
| @@ -471,13 +471,13 @@ static int kvmppc_mmu_book3s_64_hv_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, | |||
| 471 | preempt_enable(); | 471 | preempt_enable(); |
| 472 | return -ENOENT; | 472 | return -ENOENT; |
| 473 | } | 473 | } |
| 474 | hptep = (unsigned long *)(kvm->arch.hpt_virt + (index << 4)); | 474 | hptep = (__be64 *)(kvm->arch.hpt_virt + (index << 4)); |
| 475 | v = hptep[0] & ~HPTE_V_HVLOCK; | 475 | v = be64_to_cpu(hptep[0]) & ~HPTE_V_HVLOCK; |
| 476 | gr = kvm->arch.revmap[index].guest_rpte; | 476 | gr = kvm->arch.revmap[index].guest_rpte; |
| 477 | 477 | ||
| 478 | /* Unlock the HPTE */ | 478 | /* Unlock the HPTE */ |
| 479 | asm volatile("lwsync" : : : "memory"); | 479 | asm volatile("lwsync" : : : "memory"); |
| 480 | hptep[0] = v; | 480 | hptep[0] = cpu_to_be64(v); |
| 481 | preempt_enable(); | 481 | preempt_enable(); |
| 482 | 482 | ||
| 483 | gpte->eaddr = eaddr; | 483 | gpte->eaddr = eaddr; |
| @@ -528,21 +528,14 @@ static int instruction_is_store(unsigned int instr) | |||
| 528 | static int kvmppc_hv_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu, | 528 | static int kvmppc_hv_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu, |
| 529 | unsigned long gpa, gva_t ea, int is_store) | 529 | unsigned long gpa, gva_t ea, int is_store) |
| 530 | { | 530 | { |
| 531 | int ret; | ||
| 532 | u32 last_inst; | 531 | u32 last_inst; |
| 533 | unsigned long srr0 = kvmppc_get_pc(vcpu); | ||
| 534 | 532 | ||
| 535 | /* We try to load the last instruction. We don't let | 533 | /* |
| 536 | * emulate_instruction do it as it doesn't check what | ||
| 537 | * kvmppc_ld returns. | ||
| 538 | * If we fail, we just return to the guest and try executing it again. | 534 | * If we fail, we just return to the guest and try executing it again. |
| 539 | */ | 535 | */ |
| 540 | if (vcpu->arch.last_inst == KVM_INST_FETCH_FAILED) { | 536 | if (kvmppc_get_last_inst(vcpu, INST_GENERIC, &last_inst) != |
| 541 | ret = kvmppc_ld(vcpu, &srr0, sizeof(u32), &last_inst, false); | 537 | EMULATE_DONE) |
| 542 | if (ret != EMULATE_DONE || last_inst == KVM_INST_FETCH_FAILED) | 538 | return RESUME_GUEST; |
| 543 | return RESUME_GUEST; | ||
| 544 | vcpu->arch.last_inst = last_inst; | ||
| 545 | } | ||
| 546 | 539 | ||
| 547 | /* | 540 | /* |
| 548 | * WARNING: We do not know for sure whether the instruction we just | 541 | * WARNING: We do not know for sure whether the instruction we just |
| @@ -556,7 +549,7 @@ static int kvmppc_hv_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
| 556 | * we just return and retry the instruction. | 549 | * we just return and retry the instruction. |
| 557 | */ | 550 | */ |
| 558 | 551 | ||
| 559 | if (instruction_is_store(kvmppc_get_last_inst(vcpu)) != !!is_store) | 552 | if (instruction_is_store(last_inst) != !!is_store) |
| 560 | return RESUME_GUEST; | 553 | return RESUME_GUEST; |
| 561 | 554 | ||
| 562 | /* | 555 | /* |
| @@ -581,7 +574,8 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
| 581 | unsigned long ea, unsigned long dsisr) | 574 | unsigned long ea, unsigned long dsisr) |
| 582 | { | 575 | { |
| 583 | struct kvm *kvm = vcpu->kvm; | 576 | struct kvm *kvm = vcpu->kvm; |
| 584 | unsigned long *hptep, hpte[3], r; | 577 | unsigned long hpte[3], r; |
| 578 | __be64 *hptep; | ||
| 585 | unsigned long mmu_seq, psize, pte_size; | 579 | unsigned long mmu_seq, psize, pte_size; |
| 586 | unsigned long gpa_base, gfn_base; | 580 | unsigned long gpa_base, gfn_base; |
| 587 | unsigned long gpa, gfn, hva, pfn; | 581 | unsigned long gpa, gfn, hva, pfn; |
| @@ -604,16 +598,16 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
| 604 | if (ea != vcpu->arch.pgfault_addr) | 598 | if (ea != vcpu->arch.pgfault_addr) |
| 605 | return RESUME_GUEST; | 599 | return RESUME_GUEST; |
| 606 | index = vcpu->arch.pgfault_index; | 600 | index = vcpu->arch.pgfault_index; |
| 607 | hptep = (unsigned long *)(kvm->arch.hpt_virt + (index << 4)); | 601 | hptep = (__be64 *)(kvm->arch.hpt_virt + (index << 4)); |
| 608 | rev = &kvm->arch.revmap[index]; | 602 | rev = &kvm->arch.revmap[index]; |
| 609 | preempt_disable(); | 603 | preempt_disable(); |
| 610 | while (!try_lock_hpte(hptep, HPTE_V_HVLOCK)) | 604 | while (!try_lock_hpte(hptep, HPTE_V_HVLOCK)) |
| 611 | cpu_relax(); | 605 | cpu_relax(); |
| 612 | hpte[0] = hptep[0] & ~HPTE_V_HVLOCK; | 606 | hpte[0] = be64_to_cpu(hptep[0]) & ~HPTE_V_HVLOCK; |
| 613 | hpte[1] = hptep[1]; | 607 | hpte[1] = be64_to_cpu(hptep[1]); |
| 614 | hpte[2] = r = rev->guest_rpte; | 608 | hpte[2] = r = rev->guest_rpte; |
| 615 | asm volatile("lwsync" : : : "memory"); | 609 | asm volatile("lwsync" : : : "memory"); |
| 616 | hptep[0] = hpte[0]; | 610 | hptep[0] = cpu_to_be64(hpte[0]); |
| 617 | preempt_enable(); | 611 | preempt_enable(); |
| 618 | 612 | ||
| 619 | if (hpte[0] != vcpu->arch.pgfault_hpte[0] || | 613 | if (hpte[0] != vcpu->arch.pgfault_hpte[0] || |
| @@ -729,8 +723,9 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
| 729 | preempt_disable(); | 723 | preempt_disable(); |
| 730 | while (!try_lock_hpte(hptep, HPTE_V_HVLOCK)) | 724 | while (!try_lock_hpte(hptep, HPTE_V_HVLOCK)) |
| 731 | cpu_relax(); | 725 | cpu_relax(); |
| 732 | if ((hptep[0] & ~HPTE_V_HVLOCK) != hpte[0] || hptep[1] != hpte[1] || | 726 | if ((be64_to_cpu(hptep[0]) & ~HPTE_V_HVLOCK) != hpte[0] || |
| 733 | rev->guest_rpte != hpte[2]) | 727 | be64_to_cpu(hptep[1]) != hpte[1] || |
| 728 | rev->guest_rpte != hpte[2]) | ||
| 734 | /* HPTE has been changed under us; let the guest retry */ | 729 | /* HPTE has been changed under us; let the guest retry */ |
| 735 | goto out_unlock; | 730 | goto out_unlock; |
| 736 | hpte[0] = (hpte[0] & ~HPTE_V_ABSENT) | HPTE_V_VALID; | 731 | hpte[0] = (hpte[0] & ~HPTE_V_ABSENT) | HPTE_V_VALID; |
| @@ -750,20 +745,20 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
| 750 | rcbits = *rmap >> KVMPPC_RMAP_RC_SHIFT; | 745 | rcbits = *rmap >> KVMPPC_RMAP_RC_SHIFT; |
| 751 | r &= rcbits | ~(HPTE_R_R | HPTE_R_C); | 746 | r &= rcbits | ~(HPTE_R_R | HPTE_R_C); |
| 752 | 747 | ||
| 753 | if (hptep[0] & HPTE_V_VALID) { | 748 | if (be64_to_cpu(hptep[0]) & HPTE_V_VALID) { |
| 754 | /* HPTE was previously valid, so we need to invalidate it */ | 749 | /* HPTE was previously valid, so we need to invalidate it */ |
| 755 | unlock_rmap(rmap); | 750 | unlock_rmap(rmap); |
| 756 | hptep[0] |= HPTE_V_ABSENT; | 751 | hptep[0] |= cpu_to_be64(HPTE_V_ABSENT); |
| 757 | kvmppc_invalidate_hpte(kvm, hptep, index); | 752 | kvmppc_invalidate_hpte(kvm, hptep, index); |
| 758 | /* don't lose previous R and C bits */ | 753 | /* don't lose previous R and C bits */ |
| 759 | r |= hptep[1] & (HPTE_R_R | HPTE_R_C); | 754 | r |= be64_to_cpu(hptep[1]) & (HPTE_R_R | HPTE_R_C); |
| 760 | } else { | 755 | } else { |
| 761 | kvmppc_add_revmap_chain(kvm, rev, rmap, index, 0); | 756 | kvmppc_add_revmap_chain(kvm, rev, rmap, index, 0); |
| 762 | } | 757 | } |
| 763 | 758 | ||
| 764 | hptep[1] = r; | 759 | hptep[1] = cpu_to_be64(r); |
| 765 | eieio(); | 760 | eieio(); |
| 766 | hptep[0] = hpte[0]; | 761 | hptep[0] = cpu_to_be64(hpte[0]); |
| 767 | asm volatile("ptesync" : : : "memory"); | 762 | asm volatile("ptesync" : : : "memory"); |
| 768 | preempt_enable(); | 763 | preempt_enable(); |
| 769 | if (page && hpte_is_writable(r)) | 764 | if (page && hpte_is_writable(r)) |
| @@ -782,7 +777,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
| 782 | return ret; | 777 | return ret; |
| 783 | 778 | ||
| 784 | out_unlock: | 779 | out_unlock: |
| 785 | hptep[0] &= ~HPTE_V_HVLOCK; | 780 | hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK); |
| 786 | preempt_enable(); | 781 | preempt_enable(); |
| 787 | goto out_put; | 782 | goto out_put; |
| 788 | } | 783 | } |
| @@ -858,7 +853,7 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
| 858 | { | 853 | { |
| 859 | struct revmap_entry *rev = kvm->arch.revmap; | 854 | struct revmap_entry *rev = kvm->arch.revmap; |
| 860 | unsigned long h, i, j; | 855 | unsigned long h, i, j; |
| 861 | unsigned long *hptep; | 856 | __be64 *hptep; |
| 862 | unsigned long ptel, psize, rcbits; | 857 | unsigned long ptel, psize, rcbits; |
| 863 | 858 | ||
| 864 | for (;;) { | 859 | for (;;) { |
| @@ -874,11 +869,11 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
| 874 | * rmap chain lock. | 869 | * rmap chain lock. |
| 875 | */ | 870 | */ |
| 876 | i = *rmapp & KVMPPC_RMAP_INDEX; | 871 | i = *rmapp & KVMPPC_RMAP_INDEX; |
| 877 | hptep = (unsigned long *) (kvm->arch.hpt_virt + (i << 4)); | 872 | hptep = (__be64 *) (kvm->arch.hpt_virt + (i << 4)); |
| 878 | if (!try_lock_hpte(hptep, HPTE_V_HVLOCK)) { | 873 | if (!try_lock_hpte(hptep, HPTE_V_HVLOCK)) { |
| 879 | /* unlock rmap before spinning on the HPTE lock */ | 874 | /* unlock rmap before spinning on the HPTE lock */ |
| 880 | unlock_rmap(rmapp); | 875 | unlock_rmap(rmapp); |
| 881 | while (hptep[0] & HPTE_V_HVLOCK) | 876 | while (be64_to_cpu(hptep[0]) & HPTE_V_HVLOCK) |
| 882 | cpu_relax(); | 877 | cpu_relax(); |
| 883 | continue; | 878 | continue; |
| 884 | } | 879 | } |
| @@ -897,14 +892,14 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
| 897 | 892 | ||
| 898 | /* Now check and modify the HPTE */ | 893 | /* Now check and modify the HPTE */ |
| 899 | ptel = rev[i].guest_rpte; | 894 | ptel = rev[i].guest_rpte; |
| 900 | psize = hpte_page_size(hptep[0], ptel); | 895 | psize = hpte_page_size(be64_to_cpu(hptep[0]), ptel); |
| 901 | if ((hptep[0] & HPTE_V_VALID) && | 896 | if ((be64_to_cpu(hptep[0]) & HPTE_V_VALID) && |
| 902 | hpte_rpn(ptel, psize) == gfn) { | 897 | hpte_rpn(ptel, psize) == gfn) { |
| 903 | if (kvm->arch.using_mmu_notifiers) | 898 | if (kvm->arch.using_mmu_notifiers) |
| 904 | hptep[0] |= HPTE_V_ABSENT; | 899 | hptep[0] |= cpu_to_be64(HPTE_V_ABSENT); |
| 905 | kvmppc_invalidate_hpte(kvm, hptep, i); | 900 | kvmppc_invalidate_hpte(kvm, hptep, i); |
| 906 | /* Harvest R and C */ | 901 | /* Harvest R and C */ |
| 907 | rcbits = hptep[1] & (HPTE_R_R | HPTE_R_C); | 902 | rcbits = be64_to_cpu(hptep[1]) & (HPTE_R_R | HPTE_R_C); |
| 908 | *rmapp |= rcbits << KVMPPC_RMAP_RC_SHIFT; | 903 | *rmapp |= rcbits << KVMPPC_RMAP_RC_SHIFT; |
| 909 | if (rcbits & ~rev[i].guest_rpte) { | 904 | if (rcbits & ~rev[i].guest_rpte) { |
| 910 | rev[i].guest_rpte = ptel | rcbits; | 905 | rev[i].guest_rpte = ptel | rcbits; |
| @@ -912,7 +907,7 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
| 912 | } | 907 | } |
| 913 | } | 908 | } |
| 914 | unlock_rmap(rmapp); | 909 | unlock_rmap(rmapp); |
| 915 | hptep[0] &= ~HPTE_V_HVLOCK; | 910 | hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK); |
| 916 | } | 911 | } |
| 917 | return 0; | 912 | return 0; |
| 918 | } | 913 | } |
| @@ -959,7 +954,7 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
| 959 | { | 954 | { |
| 960 | struct revmap_entry *rev = kvm->arch.revmap; | 955 | struct revmap_entry *rev = kvm->arch.revmap; |
| 961 | unsigned long head, i, j; | 956 | unsigned long head, i, j; |
| 962 | unsigned long *hptep; | 957 | __be64 *hptep; |
| 963 | int ret = 0; | 958 | int ret = 0; |
| 964 | 959 | ||
| 965 | retry: | 960 | retry: |
| @@ -975,23 +970,24 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
| 975 | 970 | ||
| 976 | i = head = *rmapp & KVMPPC_RMAP_INDEX; | 971 | i = head = *rmapp & KVMPPC_RMAP_INDEX; |
| 977 | do { | 972 | do { |
| 978 | hptep = (unsigned long *) (kvm->arch.hpt_virt + (i << 4)); | 973 | hptep = (__be64 *) (kvm->arch.hpt_virt + (i << 4)); |
| 979 | j = rev[i].forw; | 974 | j = rev[i].forw; |
| 980 | 975 | ||
| 981 | /* If this HPTE isn't referenced, ignore it */ | 976 | /* If this HPTE isn't referenced, ignore it */ |
| 982 | if (!(hptep[1] & HPTE_R_R)) | 977 | if (!(be64_to_cpu(hptep[1]) & HPTE_R_R)) |
| 983 | continue; | 978 | continue; |
| 984 | 979 | ||
| 985 | if (!try_lock_hpte(hptep, HPTE_V_HVLOCK)) { | 980 | if (!try_lock_hpte(hptep, HPTE_V_HVLOCK)) { |
| 986 | /* unlock rmap before spinning on the HPTE lock */ | 981 | /* unlock rmap before spinning on the HPTE lock */ |
| 987 | unlock_rmap(rmapp); | 982 | unlock_rmap(rmapp); |
| 988 | while (hptep[0] & HPTE_V_HVLOCK) | 983 | while (be64_to_cpu(hptep[0]) & HPTE_V_HVLOCK) |
| 989 | cpu_relax(); | 984 | cpu_relax(); |
| 990 | goto retry; | 985 | goto retry; |
| 991 | } | 986 | } |
| 992 | 987 | ||
| 993 | /* Now check and modify the HPTE */ | 988 | /* Now check and modify the HPTE */ |
| 994 | if ((hptep[0] & HPTE_V_VALID) && (hptep[1] & HPTE_R_R)) { | 989 | if ((be64_to_cpu(hptep[0]) & HPTE_V_VALID) && |
| 990 | (be64_to_cpu(hptep[1]) & HPTE_R_R)) { | ||
| 995 | kvmppc_clear_ref_hpte(kvm, hptep, i); | 991 | kvmppc_clear_ref_hpte(kvm, hptep, i); |
| 996 | if (!(rev[i].guest_rpte & HPTE_R_R)) { | 992 | if (!(rev[i].guest_rpte & HPTE_R_R)) { |
| 997 | rev[i].guest_rpte |= HPTE_R_R; | 993 | rev[i].guest_rpte |= HPTE_R_R; |
| @@ -999,7 +995,7 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
| 999 | } | 995 | } |
| 1000 | ret = 1; | 996 | ret = 1; |
| 1001 | } | 997 | } |
| 1002 | hptep[0] &= ~HPTE_V_HVLOCK; | 998 | hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK); |
| 1003 | } while ((i = j) != head); | 999 | } while ((i = j) != head); |
| 1004 | 1000 | ||
| 1005 | unlock_rmap(rmapp); | 1001 | unlock_rmap(rmapp); |
| @@ -1033,7 +1029,7 @@ static int kvm_test_age_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
| 1033 | do { | 1029 | do { |
| 1034 | hp = (unsigned long *)(kvm->arch.hpt_virt + (i << 4)); | 1030 | hp = (unsigned long *)(kvm->arch.hpt_virt + (i << 4)); |
| 1035 | j = rev[i].forw; | 1031 | j = rev[i].forw; |
| 1036 | if (hp[1] & HPTE_R_R) | 1032 | if (be64_to_cpu(hp[1]) & HPTE_R_R) |
| 1037 | goto out; | 1033 | goto out; |
| 1038 | } while ((i = j) != head); | 1034 | } while ((i = j) != head); |
| 1039 | } | 1035 | } |
| @@ -1073,7 +1069,7 @@ static int kvm_test_clear_dirty_npages(struct kvm *kvm, unsigned long *rmapp) | |||
| 1073 | unsigned long head, i, j; | 1069 | unsigned long head, i, j; |
| 1074 | unsigned long n; | 1070 | unsigned long n; |
| 1075 | unsigned long v, r; | 1071 | unsigned long v, r; |
| 1076 | unsigned long *hptep; | 1072 | __be64 *hptep; |
| 1077 | int npages_dirty = 0; | 1073 | int npages_dirty = 0; |
| 1078 | 1074 | ||
| 1079 | retry: | 1075 | retry: |
| @@ -1089,7 +1085,8 @@ static int kvm_test_clear_dirty_npages(struct kvm *kvm, unsigned long *rmapp) | |||
| 1089 | 1085 | ||
| 1090 | i = head = *rmapp & KVMPPC_RMAP_INDEX; | 1086 | i = head = *rmapp & KVMPPC_RMAP_INDEX; |
| 1091 | do { | 1087 | do { |
| 1092 | hptep = (unsigned long *) (kvm->arch.hpt_virt + (i << 4)); | 1088 | unsigned long hptep1; |
| 1089 | hptep = (__be64 *) (kvm->arch.hpt_virt + (i << 4)); | ||
| 1093 | j = rev[i].forw; | 1090 | j = rev[i].forw; |
| 1094 | 1091 | ||
| 1095 | /* | 1092 | /* |
| @@ -1106,29 +1103,30 @@ static int kvm_test_clear_dirty_npages(struct kvm *kvm, unsigned long *rmapp) | |||
| 1106 | * Otherwise we need to do the tlbie even if C==0 in | 1103 | * Otherwise we need to do the tlbie even if C==0 in |
| 1107 | * order to pick up any delayed writeback of C. | 1104 | * order to pick up any delayed writeback of C. |
| 1108 | */ | 1105 | */ |
| 1109 | if (!(hptep[1] & HPTE_R_C) && | 1106 | hptep1 = be64_to_cpu(hptep[1]); |
| 1110 | (!hpte_is_writable(hptep[1]) || vcpus_running(kvm))) | 1107 | if (!(hptep1 & HPTE_R_C) && |
| 1108 | (!hpte_is_writable(hptep1) || vcpus_running(kvm))) | ||
| 1111 | continue; | 1109 | continue; |
| 1112 | 1110 | ||
| 1113 | if (!try_lock_hpte(hptep, HPTE_V_HVLOCK)) { | 1111 | if (!try_lock_hpte(hptep, HPTE_V_HVLOCK)) { |
| 1114 | /* unlock rmap before spinning on the HPTE lock */ | 1112 | /* unlock rmap before spinning on the HPTE lock */ |
| 1115 | unlock_rmap(rmapp); | 1113 | unlock_rmap(rmapp); |
| 1116 | while (hptep[0] & HPTE_V_HVLOCK) | 1114 | while (hptep[0] & cpu_to_be64(HPTE_V_HVLOCK)) |
| 1117 | cpu_relax(); | 1115 | cpu_relax(); |
| 1118 | goto retry; | 1116 | goto retry; |
| 1119 | } | 1117 | } |
| 1120 | 1118 | ||
| 1121 | /* Now check and modify the HPTE */ | 1119 | /* Now check and modify the HPTE */ |
| 1122 | if (!(hptep[0] & HPTE_V_VALID)) | 1120 | if (!(hptep[0] & cpu_to_be64(HPTE_V_VALID))) |
| 1123 | continue; | 1121 | continue; |
| 1124 | 1122 | ||
| 1125 | /* need to make it temporarily absent so C is stable */ | 1123 | /* need to make it temporarily absent so C is stable */ |
| 1126 | hptep[0] |= HPTE_V_ABSENT; | 1124 | hptep[0] |= cpu_to_be64(HPTE_V_ABSENT); |
| 1127 | kvmppc_invalidate_hpte(kvm, hptep, i); | 1125 | kvmppc_invalidate_hpte(kvm, hptep, i); |
| 1128 | v = hptep[0]; | 1126 | v = be64_to_cpu(hptep[0]); |
| 1129 | r = hptep[1]; | 1127 | r = be64_to_cpu(hptep[1]); |
| 1130 | if (r & HPTE_R_C) { | 1128 | if (r & HPTE_R_C) { |
| 1131 | hptep[1] = r & ~HPTE_R_C; | 1129 | hptep[1] = cpu_to_be64(r & ~HPTE_R_C); |
| 1132 | if (!(rev[i].guest_rpte & HPTE_R_C)) { | 1130 | if (!(rev[i].guest_rpte & HPTE_R_C)) { |
| 1133 | rev[i].guest_rpte |= HPTE_R_C; | 1131 | rev[i].guest_rpte |= HPTE_R_C; |
| 1134 | note_hpte_modification(kvm, &rev[i]); | 1132 | note_hpte_modification(kvm, &rev[i]); |
| @@ -1141,7 +1139,7 @@ static int kvm_test_clear_dirty_npages(struct kvm *kvm, unsigned long *rmapp) | |||
| 1141 | } | 1139 | } |
| 1142 | v &= ~(HPTE_V_ABSENT | HPTE_V_HVLOCK); | 1140 | v &= ~(HPTE_V_ABSENT | HPTE_V_HVLOCK); |
| 1143 | v |= HPTE_V_VALID; | 1141 | v |= HPTE_V_VALID; |
| 1144 | hptep[0] = v; | 1142 | hptep[0] = cpu_to_be64(v); |
| 1145 | } while ((i = j) != head); | 1143 | } while ((i = j) != head); |
| 1146 | 1144 | ||
| 1147 | unlock_rmap(rmapp); | 1145 | unlock_rmap(rmapp); |
| @@ -1305,7 +1303,7 @@ struct kvm_htab_ctx { | |||
| 1305 | * Returns 1 if this HPT entry has been modified or has pending | 1303 | * Returns 1 if this HPT entry has been modified or has pending |
| 1306 | * R/C bit changes. | 1304 | * R/C bit changes. |
| 1307 | */ | 1305 | */ |
| 1308 | static int hpte_dirty(struct revmap_entry *revp, unsigned long *hptp) | 1306 | static int hpte_dirty(struct revmap_entry *revp, __be64 *hptp) |
| 1309 | { | 1307 | { |
| 1310 | unsigned long rcbits_unset; | 1308 | unsigned long rcbits_unset; |
| 1311 | 1309 | ||
| @@ -1314,13 +1312,14 @@ static int hpte_dirty(struct revmap_entry *revp, unsigned long *hptp) | |||
| 1314 | 1312 | ||
| 1315 | /* Also need to consider changes in reference and changed bits */ | 1313 | /* Also need to consider changes in reference and changed bits */ |
| 1316 | rcbits_unset = ~revp->guest_rpte & (HPTE_R_R | HPTE_R_C); | 1314 | rcbits_unset = ~revp->guest_rpte & (HPTE_R_R | HPTE_R_C); |
| 1317 | if ((hptp[0] & HPTE_V_VALID) && (hptp[1] & rcbits_unset)) | 1315 | if ((be64_to_cpu(hptp[0]) & HPTE_V_VALID) && |
| 1316 | (be64_to_cpu(hptp[1]) & rcbits_unset)) | ||
| 1318 | return 1; | 1317 | return 1; |
| 1319 | 1318 | ||
| 1320 | return 0; | 1319 | return 0; |
| 1321 | } | 1320 | } |
| 1322 | 1321 | ||
| 1323 | static long record_hpte(unsigned long flags, unsigned long *hptp, | 1322 | static long record_hpte(unsigned long flags, __be64 *hptp, |
| 1324 | unsigned long *hpte, struct revmap_entry *revp, | 1323 | unsigned long *hpte, struct revmap_entry *revp, |
| 1325 | int want_valid, int first_pass) | 1324 | int want_valid, int first_pass) |
| 1326 | { | 1325 | { |
| @@ -1335,10 +1334,10 @@ static long record_hpte(unsigned long flags, unsigned long *hptp, | |||
| 1335 | return 0; | 1334 | return 0; |
| 1336 | 1335 | ||
| 1337 | valid = 0; | 1336 | valid = 0; |
| 1338 | if (hptp[0] & (HPTE_V_VALID | HPTE_V_ABSENT)) { | 1337 | if (be64_to_cpu(hptp[0]) & (HPTE_V_VALID | HPTE_V_ABSENT)) { |
| 1339 | valid = 1; | 1338 | valid = 1; |
| 1340 | if ((flags & KVM_GET_HTAB_BOLTED_ONLY) && | 1339 | if ((flags & KVM_GET_HTAB_BOLTED_ONLY) && |
| 1341 | !(hptp[0] & HPTE_V_BOLTED)) | 1340 | !(be64_to_cpu(hptp[0]) & HPTE_V_BOLTED)) |
| 1342 | valid = 0; | 1341 | valid = 0; |
| 1343 | } | 1342 | } |
| 1344 | if (valid != want_valid) | 1343 | if (valid != want_valid) |
| @@ -1350,7 +1349,7 @@ static long record_hpte(unsigned long flags, unsigned long *hptp, | |||
| 1350 | preempt_disable(); | 1349 | preempt_disable(); |
| 1351 | while (!try_lock_hpte(hptp, HPTE_V_HVLOCK)) | 1350 | while (!try_lock_hpte(hptp, HPTE_V_HVLOCK)) |
| 1352 | cpu_relax(); | 1351 | cpu_relax(); |
| 1353 | v = hptp[0]; | 1352 | v = be64_to_cpu(hptp[0]); |
| 1354 | 1353 | ||
| 1355 | /* re-evaluate valid and dirty from synchronized HPTE value */ | 1354 | /* re-evaluate valid and dirty from synchronized HPTE value */ |
| 1356 | valid = !!(v & HPTE_V_VALID); | 1355 | valid = !!(v & HPTE_V_VALID); |
| @@ -1358,9 +1357,9 @@ static long record_hpte(unsigned long flags, unsigned long *hptp, | |||
| 1358 | 1357 | ||
| 1359 | /* Harvest R and C into guest view if necessary */ | 1358 | /* Harvest R and C into guest view if necessary */ |
| 1360 | rcbits_unset = ~revp->guest_rpte & (HPTE_R_R | HPTE_R_C); | 1359 | rcbits_unset = ~revp->guest_rpte & (HPTE_R_R | HPTE_R_C); |
| 1361 | if (valid && (rcbits_unset & hptp[1])) { | 1360 | if (valid && (rcbits_unset & be64_to_cpu(hptp[1]))) { |
| 1362 | revp->guest_rpte |= (hptp[1] & (HPTE_R_R | HPTE_R_C)) | | 1361 | revp->guest_rpte |= (be64_to_cpu(hptp[1]) & |
| 1363 | HPTE_GR_MODIFIED; | 1362 | (HPTE_R_R | HPTE_R_C)) | HPTE_GR_MODIFIED; |
| 1364 | dirty = 1; | 1363 | dirty = 1; |
| 1365 | } | 1364 | } |
| 1366 | 1365 | ||
| @@ -1379,13 +1378,13 @@ static long record_hpte(unsigned long flags, unsigned long *hptp, | |||
| 1379 | revp->guest_rpte = r; | 1378 | revp->guest_rpte = r; |
| 1380 | } | 1379 | } |
| 1381 | asm volatile(PPC_RELEASE_BARRIER "" : : : "memory"); | 1380 | asm volatile(PPC_RELEASE_BARRIER "" : : : "memory"); |
| 1382 | hptp[0] &= ~HPTE_V_HVLOCK; | 1381 | hptp[0] &= ~cpu_to_be64(HPTE_V_HVLOCK); |
| 1383 | preempt_enable(); | 1382 | preempt_enable(); |
| 1384 | if (!(valid == want_valid && (first_pass || dirty))) | 1383 | if (!(valid == want_valid && (first_pass || dirty))) |
| 1385 | ok = 0; | 1384 | ok = 0; |
| 1386 | } | 1385 | } |
| 1387 | hpte[0] = v; | 1386 | hpte[0] = cpu_to_be64(v); |
| 1388 | hpte[1] = r; | 1387 | hpte[1] = cpu_to_be64(r); |
| 1389 | return ok; | 1388 | return ok; |
| 1390 | } | 1389 | } |
| 1391 | 1390 | ||
| @@ -1395,7 +1394,7 @@ static ssize_t kvm_htab_read(struct file *file, char __user *buf, | |||
| 1395 | struct kvm_htab_ctx *ctx = file->private_data; | 1394 | struct kvm_htab_ctx *ctx = file->private_data; |
| 1396 | struct kvm *kvm = ctx->kvm; | 1395 | struct kvm *kvm = ctx->kvm; |
| 1397 | struct kvm_get_htab_header hdr; | 1396 | struct kvm_get_htab_header hdr; |
| 1398 | unsigned long *hptp; | 1397 | __be64 *hptp; |
| 1399 | struct revmap_entry *revp; | 1398 | struct revmap_entry *revp; |
| 1400 | unsigned long i, nb, nw; | 1399 | unsigned long i, nb, nw; |
| 1401 | unsigned long __user *lbuf; | 1400 | unsigned long __user *lbuf; |
| @@ -1411,7 +1410,7 @@ static ssize_t kvm_htab_read(struct file *file, char __user *buf, | |||
| 1411 | flags = ctx->flags; | 1410 | flags = ctx->flags; |
| 1412 | 1411 | ||
| 1413 | i = ctx->index; | 1412 | i = ctx->index; |
| 1414 | hptp = (unsigned long *)(kvm->arch.hpt_virt + (i * HPTE_SIZE)); | 1413 | hptp = (__be64 *)(kvm->arch.hpt_virt + (i * HPTE_SIZE)); |
| 1415 | revp = kvm->arch.revmap + i; | 1414 | revp = kvm->arch.revmap + i; |
| 1416 | lbuf = (unsigned long __user *)buf; | 1415 | lbuf = (unsigned long __user *)buf; |
| 1417 | 1416 | ||
| @@ -1495,7 +1494,7 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf, | |||
| 1495 | unsigned long i, j; | 1494 | unsigned long i, j; |
| 1496 | unsigned long v, r; | 1495 | unsigned long v, r; |
| 1497 | unsigned long __user *lbuf; | 1496 | unsigned long __user *lbuf; |
| 1498 | unsigned long *hptp; | 1497 | __be64 *hptp; |
| 1499 | unsigned long tmp[2]; | 1498 | unsigned long tmp[2]; |
| 1500 | ssize_t nb; | 1499 | ssize_t nb; |
| 1501 | long int err, ret; | 1500 | long int err, ret; |
| @@ -1537,7 +1536,7 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf, | |||
| 1537 | i + hdr.n_valid + hdr.n_invalid > kvm->arch.hpt_npte) | 1536 | i + hdr.n_valid + hdr.n_invalid > kvm->arch.hpt_npte) |
| 1538 | break; | 1537 | break; |
| 1539 | 1538 | ||
| 1540 | hptp = (unsigned long *)(kvm->arch.hpt_virt + (i * HPTE_SIZE)); | 1539 | hptp = (__be64 *)(kvm->arch.hpt_virt + (i * HPTE_SIZE)); |
| 1541 | lbuf = (unsigned long __user *)buf; | 1540 | lbuf = (unsigned long __user *)buf; |
| 1542 | for (j = 0; j < hdr.n_valid; ++j) { | 1541 | for (j = 0; j < hdr.n_valid; ++j) { |
| 1543 | err = -EFAULT; | 1542 | err = -EFAULT; |
| @@ -1549,7 +1548,7 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf, | |||
| 1549 | lbuf += 2; | 1548 | lbuf += 2; |
| 1550 | nb += HPTE_SIZE; | 1549 | nb += HPTE_SIZE; |
| 1551 | 1550 | ||
| 1552 | if (hptp[0] & (HPTE_V_VALID | HPTE_V_ABSENT)) | 1551 | if (be64_to_cpu(hptp[0]) & (HPTE_V_VALID | HPTE_V_ABSENT)) |
| 1553 | kvmppc_do_h_remove(kvm, 0, i, 0, tmp); | 1552 | kvmppc_do_h_remove(kvm, 0, i, 0, tmp); |
| 1554 | err = -EIO; | 1553 | err = -EIO; |
| 1555 | ret = kvmppc_virtmode_do_h_enter(kvm, H_EXACT, i, v, r, | 1554 | ret = kvmppc_virtmode_do_h_enter(kvm, H_EXACT, i, v, r, |
| @@ -1575,7 +1574,7 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf, | |||
| 1575 | } | 1574 | } |
| 1576 | 1575 | ||
| 1577 | for (j = 0; j < hdr.n_invalid; ++j) { | 1576 | for (j = 0; j < hdr.n_invalid; ++j) { |
| 1578 | if (hptp[0] & (HPTE_V_VALID | HPTE_V_ABSENT)) | 1577 | if (be64_to_cpu(hptp[0]) & (HPTE_V_VALID | HPTE_V_ABSENT)) |
| 1579 | kvmppc_do_h_remove(kvm, 0, i, 0, tmp); | 1578 | kvmppc_do_h_remove(kvm, 0, i, 0, tmp); |
| 1580 | ++i; | 1579 | ++i; |
| 1581 | hptp += 2; | 1580 | hptp += 2; |
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index 3f295269af37..5a2bc4b0dfe5 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c | |||
| @@ -439,12 +439,6 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) | |||
| 439 | (mfmsr() & MSR_HV)) | 439 | (mfmsr() & MSR_HV)) |
| 440 | vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32; | 440 | vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32; |
| 441 | break; | 441 | break; |
| 442 | case SPRN_PURR: | ||
| 443 | to_book3s(vcpu)->purr_offset = spr_val - get_tb(); | ||
| 444 | break; | ||
| 445 | case SPRN_SPURR: | ||
| 446 | to_book3s(vcpu)->spurr_offset = spr_val - get_tb(); | ||
| 447 | break; | ||
| 448 | case SPRN_GQR0: | 442 | case SPRN_GQR0: |
| 449 | case SPRN_GQR1: | 443 | case SPRN_GQR1: |
| 450 | case SPRN_GQR2: | 444 | case SPRN_GQR2: |
| @@ -455,10 +449,10 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) | |||
| 455 | case SPRN_GQR7: | 449 | case SPRN_GQR7: |
| 456 | to_book3s(vcpu)->gqr[sprn - SPRN_GQR0] = spr_val; | 450 | to_book3s(vcpu)->gqr[sprn - SPRN_GQR0] = spr_val; |
| 457 | break; | 451 | break; |
| 452 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
| 458 | case SPRN_FSCR: | 453 | case SPRN_FSCR: |
| 459 | vcpu->arch.fscr = spr_val; | 454 | kvmppc_set_fscr(vcpu, spr_val); |
| 460 | break; | 455 | break; |
| 461 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
| 462 | case SPRN_BESCR: | 456 | case SPRN_BESCR: |
| 463 | vcpu->arch.bescr = spr_val; | 457 | vcpu->arch.bescr = spr_val; |
| 464 | break; | 458 | break; |
| @@ -572,10 +566,22 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val | |||
| 572 | *spr_val = 0; | 566 | *spr_val = 0; |
| 573 | break; | 567 | break; |
| 574 | case SPRN_PURR: | 568 | case SPRN_PURR: |
| 575 | *spr_val = get_tb() + to_book3s(vcpu)->purr_offset; | 569 | /* |
| 570 | * On exit we would have updated purr | ||
| 571 | */ | ||
| 572 | *spr_val = vcpu->arch.purr; | ||
| 576 | break; | 573 | break; |
| 577 | case SPRN_SPURR: | 574 | case SPRN_SPURR: |
| 578 | *spr_val = get_tb() + to_book3s(vcpu)->purr_offset; | 575 | /* |
| 576 | * On exit we would have updated spurr | ||
| 577 | */ | ||
| 578 | *spr_val = vcpu->arch.spurr; | ||
| 579 | break; | ||
| 580 | case SPRN_VTB: | ||
| 581 | *spr_val = vcpu->arch.vtb; | ||
| 582 | break; | ||
| 583 | case SPRN_IC: | ||
| 584 | *spr_val = vcpu->arch.ic; | ||
| 579 | break; | 585 | break; |
| 580 | case SPRN_GQR0: | 586 | case SPRN_GQR0: |
| 581 | case SPRN_GQR1: | 587 | case SPRN_GQR1: |
| @@ -587,10 +593,10 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val | |||
| 587 | case SPRN_GQR7: | 593 | case SPRN_GQR7: |
| 588 | *spr_val = to_book3s(vcpu)->gqr[sprn - SPRN_GQR0]; | 594 | *spr_val = to_book3s(vcpu)->gqr[sprn - SPRN_GQR0]; |
| 589 | break; | 595 | break; |
| 596 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
| 590 | case SPRN_FSCR: | 597 | case SPRN_FSCR: |
| 591 | *spr_val = vcpu->arch.fscr; | 598 | *spr_val = vcpu->arch.fscr; |
| 592 | break; | 599 | break; |
| 593 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
| 594 | case SPRN_BESCR: | 600 | case SPRN_BESCR: |
| 595 | *spr_val = vcpu->arch.bescr; | 601 | *spr_val = vcpu->arch.bescr; |
| 596 | break; | 602 | break; |
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 7a12edbb61e7..27cced9c7249 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | 35 | ||
| 36 | #include <asm/reg.h> | 36 | #include <asm/reg.h> |
| 37 | #include <asm/cputable.h> | 37 | #include <asm/cputable.h> |
| 38 | #include <asm/cache.h> | ||
| 38 | #include <asm/cacheflush.h> | 39 | #include <asm/cacheflush.h> |
| 39 | #include <asm/tlbflush.h> | 40 | #include <asm/tlbflush.h> |
| 40 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
| @@ -67,6 +68,15 @@ | |||
| 67 | /* Used as a "null" value for timebase values */ | 68 | /* Used as a "null" value for timebase values */ |
| 68 | #define TB_NIL (~(u64)0) | 69 | #define TB_NIL (~(u64)0) |
| 69 | 70 | ||
| 71 | static DECLARE_BITMAP(default_enabled_hcalls, MAX_HCALL_OPCODE/4 + 1); | ||
| 72 | |||
| 73 | #if defined(CONFIG_PPC_64K_PAGES) | ||
| 74 | #define MPP_BUFFER_ORDER 0 | ||
| 75 | #elif defined(CONFIG_PPC_4K_PAGES) | ||
| 76 | #define MPP_BUFFER_ORDER 3 | ||
| 77 | #endif | ||
| 78 | |||
| 79 | |||
| 70 | static void kvmppc_end_cede(struct kvm_vcpu *vcpu); | 80 | static void kvmppc_end_cede(struct kvm_vcpu *vcpu); |
| 71 | static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu); | 81 | static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu); |
| 72 | 82 | ||
| @@ -270,7 +280,7 @@ struct kvm_vcpu *kvmppc_find_vcpu(struct kvm *kvm, int id) | |||
| 270 | static void init_vpa(struct kvm_vcpu *vcpu, struct lppaca *vpa) | 280 | static void init_vpa(struct kvm_vcpu *vcpu, struct lppaca *vpa) |
| 271 | { | 281 | { |
| 272 | vpa->__old_status |= LPPACA_OLD_SHARED_PROC; | 282 | vpa->__old_status |= LPPACA_OLD_SHARED_PROC; |
| 273 | vpa->yield_count = 1; | 283 | vpa->yield_count = cpu_to_be32(1); |
| 274 | } | 284 | } |
| 275 | 285 | ||
| 276 | static int set_vpa(struct kvm_vcpu *vcpu, struct kvmppc_vpa *v, | 286 | static int set_vpa(struct kvm_vcpu *vcpu, struct kvmppc_vpa *v, |
| @@ -293,8 +303,8 @@ static int set_vpa(struct kvm_vcpu *vcpu, struct kvmppc_vpa *v, | |||
| 293 | struct reg_vpa { | 303 | struct reg_vpa { |
| 294 | u32 dummy; | 304 | u32 dummy; |
| 295 | union { | 305 | union { |
| 296 | u16 hword; | 306 | __be16 hword; |
| 297 | u32 word; | 307 | __be32 word; |
| 298 | } length; | 308 | } length; |
| 299 | }; | 309 | }; |
| 300 | 310 | ||
| @@ -333,9 +343,9 @@ static unsigned long do_h_register_vpa(struct kvm_vcpu *vcpu, | |||
| 333 | if (va == NULL) | 343 | if (va == NULL) |
| 334 | return H_PARAMETER; | 344 | return H_PARAMETER; |
| 335 | if (subfunc == H_VPA_REG_VPA) | 345 | if (subfunc == H_VPA_REG_VPA) |
| 336 | len = ((struct reg_vpa *)va)->length.hword; | 346 | len = be16_to_cpu(((struct reg_vpa *)va)->length.hword); |
| 337 | else | 347 | else |
| 338 | len = ((struct reg_vpa *)va)->length.word; | 348 | len = be32_to_cpu(((struct reg_vpa *)va)->length.word); |
| 339 | kvmppc_unpin_guest_page(kvm, va, vpa, false); | 349 | kvmppc_unpin_guest_page(kvm, va, vpa, false); |
| 340 | 350 | ||
| 341 | /* Check length */ | 351 | /* Check length */ |
| @@ -540,21 +550,63 @@ static void kvmppc_create_dtl_entry(struct kvm_vcpu *vcpu, | |||
| 540 | return; | 550 | return; |
| 541 | memset(dt, 0, sizeof(struct dtl_entry)); | 551 | memset(dt, 0, sizeof(struct dtl_entry)); |
| 542 | dt->dispatch_reason = 7; | 552 | dt->dispatch_reason = 7; |
| 543 | dt->processor_id = vc->pcpu + vcpu->arch.ptid; | 553 | dt->processor_id = cpu_to_be16(vc->pcpu + vcpu->arch.ptid); |
| 544 | dt->timebase = now + vc->tb_offset; | 554 | dt->timebase = cpu_to_be64(now + vc->tb_offset); |
| 545 | dt->enqueue_to_dispatch_time = stolen; | 555 | dt->enqueue_to_dispatch_time = cpu_to_be32(stolen); |
| 546 | dt->srr0 = kvmppc_get_pc(vcpu); | 556 | dt->srr0 = cpu_to_be64(kvmppc_get_pc(vcpu)); |
| 547 | dt->srr1 = vcpu->arch.shregs.msr; | 557 | dt->srr1 = cpu_to_be64(vcpu->arch.shregs.msr); |
| 548 | ++dt; | 558 | ++dt; |
| 549 | if (dt == vcpu->arch.dtl.pinned_end) | 559 | if (dt == vcpu->arch.dtl.pinned_end) |
| 550 | dt = vcpu->arch.dtl.pinned_addr; | 560 | dt = vcpu->arch.dtl.pinned_addr; |
| 551 | vcpu->arch.dtl_ptr = dt; | 561 | vcpu->arch.dtl_ptr = dt; |
| 552 | /* order writing *dt vs. writing vpa->dtl_idx */ | 562 | /* order writing *dt vs. writing vpa->dtl_idx */ |
| 553 | smp_wmb(); | 563 | smp_wmb(); |
| 554 | vpa->dtl_idx = ++vcpu->arch.dtl_index; | 564 | vpa->dtl_idx = cpu_to_be64(++vcpu->arch.dtl_index); |
| 555 | vcpu->arch.dtl.dirty = true; | 565 | vcpu->arch.dtl.dirty = true; |
| 556 | } | 566 | } |
| 557 | 567 | ||
| 568 | static bool kvmppc_power8_compatible(struct kvm_vcpu *vcpu) | ||
| 569 | { | ||
| 570 | if (vcpu->arch.vcore->arch_compat >= PVR_ARCH_207) | ||
| 571 | return true; | ||
| 572 | if ((!vcpu->arch.vcore->arch_compat) && | ||
| 573 | cpu_has_feature(CPU_FTR_ARCH_207S)) | ||
| 574 | return true; | ||
| 575 | return false; | ||
| 576 | } | ||
| 577 | |||
| 578 | static int kvmppc_h_set_mode(struct kvm_vcpu *vcpu, unsigned long mflags, | ||
| 579 | unsigned long resource, unsigned long value1, | ||
| 580 | unsigned long value2) | ||
| 581 | { | ||
| 582 | switch (resource) { | ||
| 583 | case H_SET_MODE_RESOURCE_SET_CIABR: | ||
| 584 | if (!kvmppc_power8_compatible(vcpu)) | ||
| 585 | return H_P2; | ||
| 586 | if (value2) | ||
| 587 | return H_P4; | ||
| 588 | if (mflags) | ||
| 589 | return H_UNSUPPORTED_FLAG_START; | ||
| 590 | /* Guests can't breakpoint the hypervisor */ | ||
| 591 | if ((value1 & CIABR_PRIV) == CIABR_PRIV_HYPER) | ||
| 592 | return H_P3; | ||
| 593 | vcpu->arch.ciabr = value1; | ||
| 594 | return H_SUCCESS; | ||
| 595 | case H_SET_MODE_RESOURCE_SET_DAWR: | ||
| 596 | if (!kvmppc_power8_compatible(vcpu)) | ||
| 597 | return H_P2; | ||
| 598 | if (mflags) | ||
| 599 | return H_UNSUPPORTED_FLAG_START; | ||
| 600 | if (value2 & DABRX_HYP) | ||
| 601 | return H_P4; | ||
| 602 | vcpu->arch.dawr = value1; | ||
| 603 | vcpu->arch.dawrx = value2; | ||
| 604 | return H_SUCCESS; | ||
| 605 | default: | ||
| 606 | return H_TOO_HARD; | ||
| 607 | } | ||
| 608 | } | ||
| 609 | |||
| 558 | int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) | 610 | int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) |
| 559 | { | 611 | { |
| 560 | unsigned long req = kvmppc_get_gpr(vcpu, 3); | 612 | unsigned long req = kvmppc_get_gpr(vcpu, 3); |
| @@ -562,6 +614,10 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) | |||
| 562 | struct kvm_vcpu *tvcpu; | 614 | struct kvm_vcpu *tvcpu; |
| 563 | int idx, rc; | 615 | int idx, rc; |
| 564 | 616 | ||
| 617 | if (req <= MAX_HCALL_OPCODE && | ||
| 618 | !test_bit(req/4, vcpu->kvm->arch.enabled_hcalls)) | ||
| 619 | return RESUME_HOST; | ||
| 620 | |||
| 565 | switch (req) { | 621 | switch (req) { |
| 566 | case H_ENTER: | 622 | case H_ENTER: |
| 567 | idx = srcu_read_lock(&vcpu->kvm->srcu); | 623 | idx = srcu_read_lock(&vcpu->kvm->srcu); |
| @@ -620,7 +676,14 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) | |||
| 620 | 676 | ||
| 621 | /* Send the error out to userspace via KVM_RUN */ | 677 | /* Send the error out to userspace via KVM_RUN */ |
| 622 | return rc; | 678 | return rc; |
| 623 | 679 | case H_SET_MODE: | |
| 680 | ret = kvmppc_h_set_mode(vcpu, kvmppc_get_gpr(vcpu, 4), | ||
| 681 | kvmppc_get_gpr(vcpu, 5), | ||
| 682 | kvmppc_get_gpr(vcpu, 6), | ||
| 683 | kvmppc_get_gpr(vcpu, 7)); | ||
| 684 | if (ret == H_TOO_HARD) | ||
| 685 | return RESUME_HOST; | ||
| 686 | break; | ||
| 624 | case H_XIRR: | 687 | case H_XIRR: |
| 625 | case H_CPPR: | 688 | case H_CPPR: |
| 626 | case H_EOI: | 689 | case H_EOI: |
| @@ -639,6 +702,29 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) | |||
| 639 | return RESUME_GUEST; | 702 | return RESUME_GUEST; |
| 640 | } | 703 | } |
| 641 | 704 | ||
| 705 | static int kvmppc_hcall_impl_hv(unsigned long cmd) | ||
| 706 | { | ||
| 707 | switch (cmd) { | ||
| 708 | case H_CEDE: | ||
| 709 | case H_PROD: | ||
| 710 | case H_CONFER: | ||
| 711 | case H_REGISTER_VPA: | ||
| 712 | case H_SET_MODE: | ||
| 713 | #ifdef CONFIG_KVM_XICS | ||
| 714 | case H_XIRR: | ||
| 715 | case H_CPPR: | ||
| 716 | case H_EOI: | ||
| 717 | case H_IPI: | ||
| 718 | case H_IPOLL: | ||
| 719 | case H_XIRR_X: | ||
| 720 | #endif | ||
| 721 | return 1; | ||
| 722 | } | ||
| 723 | |||
| 724 | /* See if it's in the real-mode table */ | ||
| 725 | return kvmppc_hcall_impl_hv_realmode(cmd); | ||
| 726 | } | ||
| 727 | |||
| 642 | static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu, | 728 | static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu, |
| 643 | struct task_struct *tsk) | 729 | struct task_struct *tsk) |
| 644 | { | 730 | { |
| @@ -785,7 +871,8 @@ static int kvm_arch_vcpu_ioctl_set_sregs_hv(struct kvm_vcpu *vcpu, | |||
| 785 | return 0; | 871 | return 0; |
| 786 | } | 872 | } |
| 787 | 873 | ||
| 788 | static void kvmppc_set_lpcr(struct kvm_vcpu *vcpu, u64 new_lpcr) | 874 | static void kvmppc_set_lpcr(struct kvm_vcpu *vcpu, u64 new_lpcr, |
| 875 | bool preserve_top32) | ||
| 789 | { | 876 | { |
| 790 | struct kvmppc_vcore *vc = vcpu->arch.vcore; | 877 | struct kvmppc_vcore *vc = vcpu->arch.vcore; |
| 791 | u64 mask; | 878 | u64 mask; |
| @@ -820,6 +907,10 @@ static void kvmppc_set_lpcr(struct kvm_vcpu *vcpu, u64 new_lpcr) | |||
| 820 | mask = LPCR_DPFD | LPCR_ILE | LPCR_TC; | 907 | mask = LPCR_DPFD | LPCR_ILE | LPCR_TC; |
| 821 | if (cpu_has_feature(CPU_FTR_ARCH_207S)) | 908 | if (cpu_has_feature(CPU_FTR_ARCH_207S)) |
| 822 | mask |= LPCR_AIL; | 909 | mask |= LPCR_AIL; |
| 910 | |||
| 911 | /* Broken 32-bit version of LPCR must not clear top bits */ | ||
| 912 | if (preserve_top32) | ||
| 913 | mask &= 0xFFFFFFFF; | ||
| 823 | vc->lpcr = (vc->lpcr & ~mask) | (new_lpcr & mask); | 914 | vc->lpcr = (vc->lpcr & ~mask) | (new_lpcr & mask); |
| 824 | spin_unlock(&vc->lock); | 915 | spin_unlock(&vc->lock); |
| 825 | } | 916 | } |
| @@ -894,12 +985,6 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, | |||
| 894 | case KVM_REG_PPC_CIABR: | 985 | case KVM_REG_PPC_CIABR: |
| 895 | *val = get_reg_val(id, vcpu->arch.ciabr); | 986 | *val = get_reg_val(id, vcpu->arch.ciabr); |
| 896 | break; | 987 | break; |
| 897 | case KVM_REG_PPC_IC: | ||
| 898 | *val = get_reg_val(id, vcpu->arch.ic); | ||
| 899 | break; | ||
| 900 | case KVM_REG_PPC_VTB: | ||
| 901 | *val = get_reg_val(id, vcpu->arch.vtb); | ||
| 902 | break; | ||
| 903 | case KVM_REG_PPC_CSIGR: | 988 | case KVM_REG_PPC_CSIGR: |
| 904 | *val = get_reg_val(id, vcpu->arch.csigr); | 989 | *val = get_reg_val(id, vcpu->arch.csigr); |
| 905 | break; | 990 | break; |
| @@ -939,6 +1024,7 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, | |||
| 939 | *val = get_reg_val(id, vcpu->arch.vcore->tb_offset); | 1024 | *val = get_reg_val(id, vcpu->arch.vcore->tb_offset); |
| 940 | break; | 1025 | break; |
| 941 | case KVM_REG_PPC_LPCR: | 1026 | case KVM_REG_PPC_LPCR: |
| 1027 | case KVM_REG_PPC_LPCR_64: | ||
| 942 | *val = get_reg_val(id, vcpu->arch.vcore->lpcr); | 1028 | *val = get_reg_val(id, vcpu->arch.vcore->lpcr); |
| 943 | break; | 1029 | break; |
| 944 | case KVM_REG_PPC_PPR: | 1030 | case KVM_REG_PPC_PPR: |
| @@ -1094,12 +1180,6 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, | |||
| 1094 | if ((vcpu->arch.ciabr & CIABR_PRIV) == CIABR_PRIV_HYPER) | 1180 | if ((vcpu->arch.ciabr & CIABR_PRIV) == CIABR_PRIV_HYPER) |
| 1095 | vcpu->arch.ciabr &= ~CIABR_PRIV; /* disable */ | 1181 | vcpu->arch.ciabr &= ~CIABR_PRIV; /* disable */ |
| 1096 | break; | 1182 | break; |
| 1097 | case KVM_REG_PPC_IC: | ||
| 1098 | vcpu->arch.ic = set_reg_val(id, *val); | ||
| 1099 | break; | ||
| 1100 | case KVM_REG_PPC_VTB: | ||
| 1101 | vcpu->arch.vtb = set_reg_val(id, *val); | ||
| 1102 | break; | ||
| 1103 | case KVM_REG_PPC_CSIGR: | 1183 | case KVM_REG_PPC_CSIGR: |
| 1104 | vcpu->arch.csigr = set_reg_val(id, *val); | 1184 | vcpu->arch.csigr = set_reg_val(id, *val); |
| 1105 | break; | 1185 | break; |
| @@ -1150,7 +1230,10 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, | |||
| 1150 | ALIGN(set_reg_val(id, *val), 1UL << 24); | 1230 | ALIGN(set_reg_val(id, *val), 1UL << 24); |
| 1151 | break; | 1231 | break; |
| 1152 | case KVM_REG_PPC_LPCR: | 1232 | case KVM_REG_PPC_LPCR: |
| 1153 | kvmppc_set_lpcr(vcpu, set_reg_val(id, *val)); | 1233 | kvmppc_set_lpcr(vcpu, set_reg_val(id, *val), true); |
| 1234 | break; | ||
| 1235 | case KVM_REG_PPC_LPCR_64: | ||
| 1236 | kvmppc_set_lpcr(vcpu, set_reg_val(id, *val), false); | ||
| 1154 | break; | 1237 | break; |
| 1155 | case KVM_REG_PPC_PPR: | 1238 | case KVM_REG_PPC_PPR: |
| 1156 | vcpu->arch.ppr = set_reg_val(id, *val); | 1239 | vcpu->arch.ppr = set_reg_val(id, *val); |
| @@ -1228,6 +1311,33 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, | |||
| 1228 | return r; | 1311 | return r; |
| 1229 | } | 1312 | } |
| 1230 | 1313 | ||
| 1314 | static struct kvmppc_vcore *kvmppc_vcore_create(struct kvm *kvm, int core) | ||
| 1315 | { | ||
| 1316 | struct kvmppc_vcore *vcore; | ||
| 1317 | |||
| 1318 | vcore = kzalloc(sizeof(struct kvmppc_vcore), GFP_KERNEL); | ||
| 1319 | |||
| 1320 | if (vcore == NULL) | ||
| 1321 | return NULL; | ||
| 1322 | |||
| 1323 | INIT_LIST_HEAD(&vcore->runnable_threads); | ||
| 1324 | spin_lock_init(&vcore->lock); | ||
| 1325 | init_waitqueue_head(&vcore->wq); | ||
| 1326 | vcore->preempt_tb = TB_NIL; | ||
| 1327 | vcore->lpcr = kvm->arch.lpcr; | ||
| 1328 | vcore->first_vcpuid = core * threads_per_subcore; | ||
| 1329 | vcore->kvm = kvm; | ||
| 1330 | |||
| 1331 | vcore->mpp_buffer_is_valid = false; | ||
| 1332 | |||
| 1333 | if (cpu_has_feature(CPU_FTR_ARCH_207S)) | ||
| 1334 | vcore->mpp_buffer = (void *)__get_free_pages( | ||
| 1335 | GFP_KERNEL|__GFP_ZERO, | ||
| 1336 | MPP_BUFFER_ORDER); | ||
| 1337 | |||
| 1338 | return vcore; | ||
| 1339 | } | ||
| 1340 | |||
| 1231 | static struct kvm_vcpu *kvmppc_core_vcpu_create_hv(struct kvm *kvm, | 1341 | static struct kvm_vcpu *kvmppc_core_vcpu_create_hv(struct kvm *kvm, |
| 1232 | unsigned int id) | 1342 | unsigned int id) |
| 1233 | { | 1343 | { |
| @@ -1279,16 +1389,7 @@ static struct kvm_vcpu *kvmppc_core_vcpu_create_hv(struct kvm *kvm, | |||
| 1279 | mutex_lock(&kvm->lock); | 1389 | mutex_lock(&kvm->lock); |
| 1280 | vcore = kvm->arch.vcores[core]; | 1390 | vcore = kvm->arch.vcores[core]; |
| 1281 | if (!vcore) { | 1391 | if (!vcore) { |
| 1282 | vcore = kzalloc(sizeof(struct kvmppc_vcore), GFP_KERNEL); | 1392 | vcore = kvmppc_vcore_create(kvm, core); |
| 1283 | if (vcore) { | ||
| 1284 | INIT_LIST_HEAD(&vcore->runnable_threads); | ||
| 1285 | spin_lock_init(&vcore->lock); | ||
| 1286 | init_waitqueue_head(&vcore->wq); | ||
| 1287 | vcore->preempt_tb = TB_NIL; | ||
| 1288 | vcore->lpcr = kvm->arch.lpcr; | ||
| 1289 | vcore->first_vcpuid = core * threads_per_subcore; | ||
| 1290 | vcore->kvm = kvm; | ||
| 1291 | } | ||
| 1292 | kvm->arch.vcores[core] = vcore; | 1393 | kvm->arch.vcores[core] = vcore; |
| 1293 | kvm->arch.online_vcores++; | 1394 | kvm->arch.online_vcores++; |
| 1294 | } | 1395 | } |
| @@ -1500,6 +1601,33 @@ static int on_primary_thread(void) | |||
| 1500 | return 1; | 1601 | return 1; |
| 1501 | } | 1602 | } |
| 1502 | 1603 | ||
| 1604 | static void kvmppc_start_saving_l2_cache(struct kvmppc_vcore *vc) | ||
| 1605 | { | ||
| 1606 | phys_addr_t phy_addr, mpp_addr; | ||
| 1607 | |||
| 1608 | phy_addr = (phys_addr_t)virt_to_phys(vc->mpp_buffer); | ||
| 1609 | mpp_addr = phy_addr & PPC_MPPE_ADDRESS_MASK; | ||
| 1610 | |||
| 1611 | mtspr(SPRN_MPPR, mpp_addr | PPC_MPPR_FETCH_ABORT); | ||
| 1612 | logmpp(mpp_addr | PPC_LOGMPP_LOG_L2); | ||
| 1613 | |||
| 1614 | vc->mpp_buffer_is_valid = true; | ||
| 1615 | } | ||
| 1616 | |||
| 1617 | static void kvmppc_start_restoring_l2_cache(const struct kvmppc_vcore *vc) | ||
| 1618 | { | ||
| 1619 | phys_addr_t phy_addr, mpp_addr; | ||
| 1620 | |||
| 1621 | phy_addr = virt_to_phys(vc->mpp_buffer); | ||
| 1622 | mpp_addr = phy_addr & PPC_MPPE_ADDRESS_MASK; | ||
| 1623 | |||
| 1624 | /* We must abort any in-progress save operations to ensure | ||
| 1625 | * the table is valid so that prefetch engine knows when to | ||
| 1626 | * stop prefetching. */ | ||
| 1627 | logmpp(mpp_addr | PPC_LOGMPP_LOG_ABORT); | ||
| 1628 | mtspr(SPRN_MPPR, mpp_addr | PPC_MPPR_FETCH_WHOLE_TABLE); | ||
| 1629 | } | ||
| 1630 | |||
| 1503 | /* | 1631 | /* |
| 1504 | * Run a set of guest threads on a physical core. | 1632 | * Run a set of guest threads on a physical core. |
| 1505 | * Called with vc->lock held. | 1633 | * Called with vc->lock held. |
| @@ -1577,9 +1705,16 @@ static void kvmppc_run_core(struct kvmppc_vcore *vc) | |||
| 1577 | 1705 | ||
| 1578 | srcu_idx = srcu_read_lock(&vc->kvm->srcu); | 1706 | srcu_idx = srcu_read_lock(&vc->kvm->srcu); |
| 1579 | 1707 | ||
| 1708 | if (vc->mpp_buffer_is_valid) | ||
| 1709 | kvmppc_start_restoring_l2_cache(vc); | ||
| 1710 | |||
| 1580 | __kvmppc_vcore_entry(); | 1711 | __kvmppc_vcore_entry(); |
| 1581 | 1712 | ||
| 1582 | spin_lock(&vc->lock); | 1713 | spin_lock(&vc->lock); |
| 1714 | |||
| 1715 | if (vc->mpp_buffer) | ||
| 1716 | kvmppc_start_saving_l2_cache(vc); | ||
| 1717 | |||
| 1583 | /* disable sending of IPIs on virtual external irqs */ | 1718 | /* disable sending of IPIs on virtual external irqs */ |
| 1584 | list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) | 1719 | list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) |
| 1585 | vcpu->cpu = -1; | 1720 | vcpu->cpu = -1; |
| @@ -1929,12 +2064,6 @@ static void kvmppc_add_seg_page_size(struct kvm_ppc_one_seg_page_size **sps, | |||
| 1929 | (*sps)->page_shift = def->shift; | 2064 | (*sps)->page_shift = def->shift; |
| 1930 | (*sps)->slb_enc = def->sllp; | 2065 | (*sps)->slb_enc = def->sllp; |
| 1931 | (*sps)->enc[0].page_shift = def->shift; | 2066 | (*sps)->enc[0].page_shift = def->shift; |
| 1932 | /* | ||
| 1933 | * Only return base page encoding. We don't want to return | ||
| 1934 | * all the supporting pte_enc, because our H_ENTER doesn't | ||
| 1935 | * support MPSS yet. Once they do, we can start passing all | ||
| 1936 | * support pte_enc here | ||
| 1937 | */ | ||
| 1938 | (*sps)->enc[0].pte_enc = def->penc[linux_psize]; | 2067 | (*sps)->enc[0].pte_enc = def->penc[linux_psize]; |
| 1939 | /* | 2068 | /* |
| 1940 | * Add 16MB MPSS support if host supports it | 2069 | * Add 16MB MPSS support if host supports it |
| @@ -2281,6 +2410,10 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm) | |||
| 2281 | */ | 2410 | */ |
| 2282 | cpumask_setall(&kvm->arch.need_tlb_flush); | 2411 | cpumask_setall(&kvm->arch.need_tlb_flush); |
| 2283 | 2412 | ||
| 2413 | /* Start out with the default set of hcalls enabled */ | ||
| 2414 | memcpy(kvm->arch.enabled_hcalls, default_enabled_hcalls, | ||
| 2415 | sizeof(kvm->arch.enabled_hcalls)); | ||
| 2416 | |||
| 2284 | kvm->arch.rma = NULL; | 2417 | kvm->arch.rma = NULL; |
| 2285 | 2418 | ||
| 2286 | kvm->arch.host_sdr1 = mfspr(SPRN_SDR1); | 2419 | kvm->arch.host_sdr1 = mfspr(SPRN_SDR1); |
| @@ -2323,8 +2456,14 @@ static void kvmppc_free_vcores(struct kvm *kvm) | |||
| 2323 | { | 2456 | { |
| 2324 | long int i; | 2457 | long int i; |
| 2325 | 2458 | ||
| 2326 | for (i = 0; i < KVM_MAX_VCORES; ++i) | 2459 | for (i = 0; i < KVM_MAX_VCORES; ++i) { |
| 2460 | if (kvm->arch.vcores[i] && kvm->arch.vcores[i]->mpp_buffer) { | ||
| 2461 | struct kvmppc_vcore *vc = kvm->arch.vcores[i]; | ||
| 2462 | free_pages((unsigned long)vc->mpp_buffer, | ||
| 2463 | MPP_BUFFER_ORDER); | ||
| 2464 | } | ||
| 2327 | kfree(kvm->arch.vcores[i]); | 2465 | kfree(kvm->arch.vcores[i]); |
| 2466 | } | ||
| 2328 | kvm->arch.online_vcores = 0; | 2467 | kvm->arch.online_vcores = 0; |
| 2329 | } | 2468 | } |
| 2330 | 2469 | ||
| @@ -2419,6 +2558,49 @@ static long kvm_arch_vm_ioctl_hv(struct file *filp, | |||
| 2419 | return r; | 2558 | return r; |
| 2420 | } | 2559 | } |
| 2421 | 2560 | ||
| 2561 | /* | ||
| 2562 | * List of hcall numbers to enable by default. | ||
| 2563 | * For compatibility with old userspace, we enable by default | ||
| 2564 | * all hcalls that were implemented before the hcall-enabling | ||
| 2565 | * facility was added. Note this list should not include H_RTAS. | ||
| 2566 | */ | ||
| 2567 | static unsigned int default_hcall_list[] = { | ||
| 2568 | H_REMOVE, | ||
| 2569 | H_ENTER, | ||
| 2570 | H_READ, | ||
| 2571 | H_PROTECT, | ||
| 2572 | H_BULK_REMOVE, | ||
| 2573 | H_GET_TCE, | ||
| 2574 | H_PUT_TCE, | ||
| 2575 | H_SET_DABR, | ||
| 2576 | H_SET_XDABR, | ||
| 2577 | H_CEDE, | ||
| 2578 | H_PROD, | ||
| 2579 | H_CONFER, | ||
| 2580 | H_REGISTER_VPA, | ||
| 2581 | #ifdef CONFIG_KVM_XICS | ||
| 2582 | H_EOI, | ||
| 2583 | H_CPPR, | ||
| 2584 | H_IPI, | ||
| 2585 | H_IPOLL, | ||
| 2586 | H_XIRR, | ||
| 2587 | H_XIRR_X, | ||
| 2588 | #endif | ||
| 2589 | 0 | ||
| 2590 | }; | ||
| 2591 | |||
| 2592 | static void init_default_hcalls(void) | ||
| 2593 | { | ||
| 2594 | int i; | ||
| 2595 | unsigned int hcall; | ||
| 2596 | |||
| 2597 | for (i = 0; default_hcall_list[i]; ++i) { | ||
| 2598 | hcall = default_hcall_list[i]; | ||
| 2599 | WARN_ON(!kvmppc_hcall_impl_hv(hcall)); | ||
| 2600 | __set_bit(hcall / 4, default_enabled_hcalls); | ||
| 2601 | } | ||
| 2602 | } | ||
| 2603 | |||
| 2422 | static struct kvmppc_ops kvm_ops_hv = { | 2604 | static struct kvmppc_ops kvm_ops_hv = { |
| 2423 | .get_sregs = kvm_arch_vcpu_ioctl_get_sregs_hv, | 2605 | .get_sregs = kvm_arch_vcpu_ioctl_get_sregs_hv, |
| 2424 | .set_sregs = kvm_arch_vcpu_ioctl_set_sregs_hv, | 2606 | .set_sregs = kvm_arch_vcpu_ioctl_set_sregs_hv, |
| @@ -2451,6 +2633,7 @@ static struct kvmppc_ops kvm_ops_hv = { | |||
| 2451 | .emulate_mfspr = kvmppc_core_emulate_mfspr_hv, | 2633 | .emulate_mfspr = kvmppc_core_emulate_mfspr_hv, |
| 2452 | .fast_vcpu_kick = kvmppc_fast_vcpu_kick_hv, | 2634 | .fast_vcpu_kick = kvmppc_fast_vcpu_kick_hv, |
| 2453 | .arch_vm_ioctl = kvm_arch_vm_ioctl_hv, | 2635 | .arch_vm_ioctl = kvm_arch_vm_ioctl_hv, |
| 2636 | .hcall_implemented = kvmppc_hcall_impl_hv, | ||
| 2454 | }; | 2637 | }; |
| 2455 | 2638 | ||
| 2456 | static int kvmppc_book3s_init_hv(void) | 2639 | static int kvmppc_book3s_init_hv(void) |
| @@ -2466,6 +2649,8 @@ static int kvmppc_book3s_init_hv(void) | |||
| 2466 | kvm_ops_hv.owner = THIS_MODULE; | 2649 | kvm_ops_hv.owner = THIS_MODULE; |
| 2467 | kvmppc_hv_ops = &kvm_ops_hv; | 2650 | kvmppc_hv_ops = &kvm_ops_hv; |
| 2468 | 2651 | ||
| 2652 | init_default_hcalls(); | ||
| 2653 | |||
| 2469 | r = kvmppc_mmu_hv_init(); | 2654 | r = kvmppc_mmu_hv_init(); |
| 2470 | return r; | 2655 | return r; |
| 2471 | } | 2656 | } |
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index 6cf498a9bc98..329d7fdd0a6a 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c | |||
| @@ -219,3 +219,16 @@ bool kvm_hv_mode_active(void) | |||
| 219 | { | 219 | { |
| 220 | return atomic_read(&hv_vm_count) != 0; | 220 | return atomic_read(&hv_vm_count) != 0; |
| 221 | } | 221 | } |
| 222 | |||
| 223 | extern int hcall_real_table[], hcall_real_table_end[]; | ||
| 224 | |||
| 225 | int kvmppc_hcall_impl_hv_realmode(unsigned long cmd) | ||
| 226 | { | ||
| 227 | cmd /= 4; | ||
| 228 | if (cmd < hcall_real_table_end - hcall_real_table && | ||
| 229 | hcall_real_table[cmd]) | ||
| 230 | return 1; | ||
| 231 | |||
| 232 | return 0; | ||
| 233 | } | ||
| 234 | EXPORT_SYMBOL_GPL(kvmppc_hcall_impl_hv_realmode); | ||
diff --git a/arch/powerpc/kvm/book3s_hv_ras.c b/arch/powerpc/kvm/book3s_hv_ras.c index 3a5c568b1e89..d562c8e2bc30 100644 --- a/arch/powerpc/kvm/book3s_hv_ras.c +++ b/arch/powerpc/kvm/book3s_hv_ras.c | |||
| @@ -45,14 +45,14 @@ static void reload_slb(struct kvm_vcpu *vcpu) | |||
| 45 | return; | 45 | return; |
| 46 | 46 | ||
| 47 | /* Sanity check */ | 47 | /* Sanity check */ |
| 48 | n = min_t(u32, slb->persistent, SLB_MIN_SIZE); | 48 | n = min_t(u32, be32_to_cpu(slb->persistent), SLB_MIN_SIZE); |
| 49 | if ((void *) &slb->save_area[n] > vcpu->arch.slb_shadow.pinned_end) | 49 | if ((void *) &slb->save_area[n] > vcpu->arch.slb_shadow.pinned_end) |
| 50 | return; | 50 | return; |
| 51 | 51 | ||
| 52 | /* Load up the SLB from that */ | 52 | /* Load up the SLB from that */ |
| 53 | for (i = 0; i < n; ++i) { | 53 | for (i = 0; i < n; ++i) { |
| 54 | unsigned long rb = slb->save_area[i].esid; | 54 | unsigned long rb = be64_to_cpu(slb->save_area[i].esid); |
| 55 | unsigned long rs = slb->save_area[i].vsid; | 55 | unsigned long rs = be64_to_cpu(slb->save_area[i].vsid); |
| 56 | 56 | ||
| 57 | rb = (rb & ~0xFFFul) | i; /* insert entry number */ | 57 | rb = (rb & ~0xFFFul) | i; /* insert entry number */ |
| 58 | asm volatile("slbmte %0,%1" : : "r" (rs), "r" (rb)); | 58 | asm volatile("slbmte %0,%1" : : "r" (rs), "r" (rb)); |
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index 5a24d3c2b6b8..084ad54c73cd 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c | |||
| @@ -154,10 +154,10 @@ static pte_t lookup_linux_pte_and_update(pgd_t *pgdir, unsigned long hva, | |||
| 154 | return kvmppc_read_update_linux_pte(ptep, writing, hugepage_shift); | 154 | return kvmppc_read_update_linux_pte(ptep, writing, hugepage_shift); |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | static inline void unlock_hpte(unsigned long *hpte, unsigned long hpte_v) | 157 | static inline void unlock_hpte(__be64 *hpte, unsigned long hpte_v) |
| 158 | { | 158 | { |
| 159 | asm volatile(PPC_RELEASE_BARRIER "" : : : "memory"); | 159 | asm volatile(PPC_RELEASE_BARRIER "" : : : "memory"); |
| 160 | hpte[0] = hpte_v; | 160 | hpte[0] = cpu_to_be64(hpte_v); |
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, | 163 | long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, |
| @@ -166,7 +166,7 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, | |||
| 166 | { | 166 | { |
| 167 | unsigned long i, pa, gpa, gfn, psize; | 167 | unsigned long i, pa, gpa, gfn, psize; |
| 168 | unsigned long slot_fn, hva; | 168 | unsigned long slot_fn, hva; |
| 169 | unsigned long *hpte; | 169 | __be64 *hpte; |
| 170 | struct revmap_entry *rev; | 170 | struct revmap_entry *rev; |
| 171 | unsigned long g_ptel; | 171 | unsigned long g_ptel; |
| 172 | struct kvm_memory_slot *memslot; | 172 | struct kvm_memory_slot *memslot; |
| @@ -275,9 +275,9 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, | |||
| 275 | return H_PARAMETER; | 275 | return H_PARAMETER; |
| 276 | if (likely((flags & H_EXACT) == 0)) { | 276 | if (likely((flags & H_EXACT) == 0)) { |
| 277 | pte_index &= ~7UL; | 277 | pte_index &= ~7UL; |
| 278 | hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); | 278 | hpte = (__be64 *)(kvm->arch.hpt_virt + (pte_index << 4)); |
| 279 | for (i = 0; i < 8; ++i) { | 279 | for (i = 0; i < 8; ++i) { |
| 280 | if ((*hpte & HPTE_V_VALID) == 0 && | 280 | if ((be64_to_cpu(*hpte) & HPTE_V_VALID) == 0 && |
| 281 | try_lock_hpte(hpte, HPTE_V_HVLOCK | HPTE_V_VALID | | 281 | try_lock_hpte(hpte, HPTE_V_HVLOCK | HPTE_V_VALID | |
| 282 | HPTE_V_ABSENT)) | 282 | HPTE_V_ABSENT)) |
| 283 | break; | 283 | break; |
| @@ -292,11 +292,13 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, | |||
| 292 | */ | 292 | */ |
| 293 | hpte -= 16; | 293 | hpte -= 16; |
| 294 | for (i = 0; i < 8; ++i) { | 294 | for (i = 0; i < 8; ++i) { |
| 295 | u64 pte; | ||
| 295 | while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) | 296 | while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) |
| 296 | cpu_relax(); | 297 | cpu_relax(); |
| 297 | if (!(*hpte & (HPTE_V_VALID | HPTE_V_ABSENT))) | 298 | pte = be64_to_cpu(*hpte); |
| 299 | if (!(pte & (HPTE_V_VALID | HPTE_V_ABSENT))) | ||
| 298 | break; | 300 | break; |
| 299 | *hpte &= ~HPTE_V_HVLOCK; | 301 | *hpte &= ~cpu_to_be64(HPTE_V_HVLOCK); |
| 300 | hpte += 2; | 302 | hpte += 2; |
| 301 | } | 303 | } |
| 302 | if (i == 8) | 304 | if (i == 8) |
| @@ -304,14 +306,17 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, | |||
| 304 | } | 306 | } |
| 305 | pte_index += i; | 307 | pte_index += i; |
| 306 | } else { | 308 | } else { |
| 307 | hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); | 309 | hpte = (__be64 *)(kvm->arch.hpt_virt + (pte_index << 4)); |
| 308 | if (!try_lock_hpte(hpte, HPTE_V_HVLOCK | HPTE_V_VALID | | 310 | if (!try_lock_hpte(hpte, HPTE_V_HVLOCK | HPTE_V_VALID | |
| 309 | HPTE_V_ABSENT)) { | 311 | HPTE_V_ABSENT)) { |
| 310 | /* Lock the slot and check again */ | 312 | /* Lock the slot and check again */ |
| 313 | u64 pte; | ||
| 314 | |||
| 311 | while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) | 315 | while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) |
| 312 | cpu_relax(); | 316 | cpu_relax(); |
| 313 | if (*hpte & (HPTE_V_VALID | HPTE_V_ABSENT)) { | 317 | pte = be64_to_cpu(*hpte); |
| 314 | *hpte &= ~HPTE_V_HVLOCK; | 318 | if (pte & (HPTE_V_VALID | HPTE_V_ABSENT)) { |
| 319 | *hpte &= ~cpu_to_be64(HPTE_V_HVLOCK); | ||
| 315 | return H_PTEG_FULL; | 320 | return H_PTEG_FULL; |
| 316 | } | 321 | } |
| 317 | } | 322 | } |
| @@ -347,11 +352,11 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, | |||
| 347 | } | 352 | } |
| 348 | } | 353 | } |
| 349 | 354 | ||
| 350 | hpte[1] = ptel; | 355 | hpte[1] = cpu_to_be64(ptel); |
| 351 | 356 | ||
| 352 | /* Write the first HPTE dword, unlocking the HPTE and making it valid */ | 357 | /* Write the first HPTE dword, unlocking the HPTE and making it valid */ |
| 353 | eieio(); | 358 | eieio(); |
| 354 | hpte[0] = pteh; | 359 | hpte[0] = cpu_to_be64(pteh); |
| 355 | asm volatile("ptesync" : : : "memory"); | 360 | asm volatile("ptesync" : : : "memory"); |
| 356 | 361 | ||
| 357 | *pte_idx_ret = pte_index; | 362 | *pte_idx_ret = pte_index; |
| @@ -468,30 +473,35 @@ long kvmppc_do_h_remove(struct kvm *kvm, unsigned long flags, | |||
| 468 | unsigned long pte_index, unsigned long avpn, | 473 | unsigned long pte_index, unsigned long avpn, |
| 469 | unsigned long *hpret) | 474 | unsigned long *hpret) |
| 470 | { | 475 | { |
| 471 | unsigned long *hpte; | 476 | __be64 *hpte; |
| 472 | unsigned long v, r, rb; | 477 | unsigned long v, r, rb; |
| 473 | struct revmap_entry *rev; | 478 | struct revmap_entry *rev; |
| 479 | u64 pte; | ||
| 474 | 480 | ||
| 475 | if (pte_index >= kvm->arch.hpt_npte) | 481 | if (pte_index >= kvm->arch.hpt_npte) |
| 476 | return H_PARAMETER; | 482 | return H_PARAMETER; |
| 477 | hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); | 483 | hpte = (__be64 *)(kvm->arch.hpt_virt + (pte_index << 4)); |
| 478 | while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) | 484 | while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) |
| 479 | cpu_relax(); | 485 | cpu_relax(); |
| 480 | if ((hpte[0] & (HPTE_V_ABSENT | HPTE_V_VALID)) == 0 || | 486 | pte = be64_to_cpu(hpte[0]); |
| 481 | ((flags & H_AVPN) && (hpte[0] & ~0x7fUL) != avpn) || | 487 | if ((pte & (HPTE_V_ABSENT | HPTE_V_VALID)) == 0 || |
| 482 | ((flags & H_ANDCOND) && (hpte[0] & avpn) != 0)) { | 488 | ((flags & H_AVPN) && (pte & ~0x7fUL) != avpn) || |
| 483 | hpte[0] &= ~HPTE_V_HVLOCK; | 489 | ((flags & H_ANDCOND) && (pte & avpn) != 0)) { |
| 490 | hpte[0] &= ~cpu_to_be64(HPTE_V_HVLOCK); | ||
| 484 | return H_NOT_FOUND; | 491 | return H_NOT_FOUND; |
| 485 | } | 492 | } |
| 486 | 493 | ||
| 487 | rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]); | 494 | rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]); |
| 488 | v = hpte[0] & ~HPTE_V_HVLOCK; | 495 | v = pte & ~HPTE_V_HVLOCK; |
| 489 | if (v & HPTE_V_VALID) { | 496 | if (v & HPTE_V_VALID) { |
| 490 | hpte[0] &= ~HPTE_V_VALID; | 497 | u64 pte1; |
| 491 | rb = compute_tlbie_rb(v, hpte[1], pte_index); | 498 | |
| 499 | pte1 = be64_to_cpu(hpte[1]); | ||
| 500 | hpte[0] &= ~cpu_to_be64(HPTE_V_VALID); | ||
| 501 | rb = compute_tlbie_rb(v, pte1, pte_index); | ||
| 492 | do_tlbies(kvm, &rb, 1, global_invalidates(kvm, flags), true); | 502 | do_tlbies(kvm, &rb, 1, global_invalidates(kvm, flags), true); |
| 493 | /* Read PTE low word after tlbie to get final R/C values */ | 503 | /* Read PTE low word after tlbie to get final R/C values */ |
| 494 | remove_revmap_chain(kvm, pte_index, rev, v, hpte[1]); | 504 | remove_revmap_chain(kvm, pte_index, rev, v, pte1); |
| 495 | } | 505 | } |
| 496 | r = rev->guest_rpte & ~HPTE_GR_RESERVED; | 506 | r = rev->guest_rpte & ~HPTE_GR_RESERVED; |
| 497 | note_hpte_modification(kvm, rev); | 507 | note_hpte_modification(kvm, rev); |
| @@ -514,12 +524,14 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu) | |||
| 514 | { | 524 | { |
| 515 | struct kvm *kvm = vcpu->kvm; | 525 | struct kvm *kvm = vcpu->kvm; |
| 516 | unsigned long *args = &vcpu->arch.gpr[4]; | 526 | unsigned long *args = &vcpu->arch.gpr[4]; |
| 517 | unsigned long *hp, *hptes[4], tlbrb[4]; | 527 | __be64 *hp, *hptes[4]; |
| 528 | unsigned long tlbrb[4]; | ||
| 518 | long int i, j, k, n, found, indexes[4]; | 529 | long int i, j, k, n, found, indexes[4]; |
| 519 | unsigned long flags, req, pte_index, rcbits; | 530 | unsigned long flags, req, pte_index, rcbits; |
| 520 | int global; | 531 | int global; |
| 521 | long int ret = H_SUCCESS; | 532 | long int ret = H_SUCCESS; |
| 522 | struct revmap_entry *rev, *revs[4]; | 533 | struct revmap_entry *rev, *revs[4]; |
| 534 | u64 hp0; | ||
| 523 | 535 | ||
| 524 | global = global_invalidates(kvm, 0); | 536 | global = global_invalidates(kvm, 0); |
| 525 | for (i = 0; i < 4 && ret == H_SUCCESS; ) { | 537 | for (i = 0; i < 4 && ret == H_SUCCESS; ) { |
| @@ -542,8 +554,7 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu) | |||
| 542 | ret = H_PARAMETER; | 554 | ret = H_PARAMETER; |
| 543 | break; | 555 | break; |
| 544 | } | 556 | } |
| 545 | hp = (unsigned long *) | 557 | hp = (__be64 *) (kvm->arch.hpt_virt + (pte_index << 4)); |
| 546 | (kvm->arch.hpt_virt + (pte_index << 4)); | ||
| 547 | /* to avoid deadlock, don't spin except for first */ | 558 | /* to avoid deadlock, don't spin except for first */ |
| 548 | if (!try_lock_hpte(hp, HPTE_V_HVLOCK)) { | 559 | if (!try_lock_hpte(hp, HPTE_V_HVLOCK)) { |
| 549 | if (n) | 560 | if (n) |
| @@ -552,23 +563,24 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu) | |||
| 552 | cpu_relax(); | 563 | cpu_relax(); |
| 553 | } | 564 | } |
| 554 | found = 0; | 565 | found = 0; |
| 555 | if (hp[0] & (HPTE_V_ABSENT | HPTE_V_VALID)) { | 566 | hp0 = be64_to_cpu(hp[0]); |
| 567 | if (hp0 & (HPTE_V_ABSENT | HPTE_V_VALID)) { | ||
| 556 | switch (flags & 3) { | 568 | switch (flags & 3) { |
| 557 | case 0: /* absolute */ | 569 | case 0: /* absolute */ |
| 558 | found = 1; | 570 | found = 1; |
| 559 | break; | 571 | break; |
| 560 | case 1: /* andcond */ | 572 | case 1: /* andcond */ |
| 561 | if (!(hp[0] & args[j + 1])) | 573 | if (!(hp0 & args[j + 1])) |
| 562 | found = 1; | 574 | found = 1; |
| 563 | break; | 575 | break; |
| 564 | case 2: /* AVPN */ | 576 | case 2: /* AVPN */ |
| 565 | if ((hp[0] & ~0x7fUL) == args[j + 1]) | 577 | if ((hp0 & ~0x7fUL) == args[j + 1]) |
| 566 | found = 1; | 578 | found = 1; |
| 567 | break; | 579 | break; |
| 568 | } | 580 | } |
| 569 | } | 581 | } |
| 570 | if (!found) { | 582 | if (!found) { |
| 571 | hp[0] &= ~HPTE_V_HVLOCK; | 583 | hp[0] &= ~cpu_to_be64(HPTE_V_HVLOCK); |
| 572 | args[j] = ((0x90 | flags) << 56) + pte_index; | 584 | args[j] = ((0x90 | flags) << 56) + pte_index; |
| 573 | continue; | 585 | continue; |
| 574 | } | 586 | } |
| @@ -577,7 +589,7 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu) | |||
| 577 | rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]); | 589 | rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]); |
| 578 | note_hpte_modification(kvm, rev); | 590 | note_hpte_modification(kvm, rev); |
| 579 | 591 | ||
| 580 | if (!(hp[0] & HPTE_V_VALID)) { | 592 | if (!(hp0 & HPTE_V_VALID)) { |
| 581 | /* insert R and C bits from PTE */ | 593 | /* insert R and C bits from PTE */ |
| 582 | rcbits = rev->guest_rpte & (HPTE_R_R|HPTE_R_C); | 594 | rcbits = rev->guest_rpte & (HPTE_R_R|HPTE_R_C); |
| 583 | args[j] |= rcbits << (56 - 5); | 595 | args[j] |= rcbits << (56 - 5); |
| @@ -585,8 +597,10 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu) | |||
| 585 | continue; | 597 | continue; |
| 586 | } | 598 | } |
| 587 | 599 | ||
| 588 | hp[0] &= ~HPTE_V_VALID; /* leave it locked */ | 600 | /* leave it locked */ |
| 589 | tlbrb[n] = compute_tlbie_rb(hp[0], hp[1], pte_index); | 601 | hp[0] &= ~cpu_to_be64(HPTE_V_VALID); |
| 602 | tlbrb[n] = compute_tlbie_rb(be64_to_cpu(hp[0]), | ||
| 603 | be64_to_cpu(hp[1]), pte_index); | ||
| 590 | indexes[n] = j; | 604 | indexes[n] = j; |
| 591 | hptes[n] = hp; | 605 | hptes[n] = hp; |
| 592 | revs[n] = rev; | 606 | revs[n] = rev; |
| @@ -605,7 +619,8 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu) | |||
| 605 | pte_index = args[j] & ((1ul << 56) - 1); | 619 | pte_index = args[j] & ((1ul << 56) - 1); |
| 606 | hp = hptes[k]; | 620 | hp = hptes[k]; |
| 607 | rev = revs[k]; | 621 | rev = revs[k]; |
| 608 | remove_revmap_chain(kvm, pte_index, rev, hp[0], hp[1]); | 622 | remove_revmap_chain(kvm, pte_index, rev, |
| 623 | be64_to_cpu(hp[0]), be64_to_cpu(hp[1])); | ||
| 609 | rcbits = rev->guest_rpte & (HPTE_R_R|HPTE_R_C); | 624 | rcbits = rev->guest_rpte & (HPTE_R_R|HPTE_R_C); |
| 610 | args[j] |= rcbits << (56 - 5); | 625 | args[j] |= rcbits << (56 - 5); |
| 611 | hp[0] = 0; | 626 | hp[0] = 0; |
| @@ -620,23 +635,25 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags, | |||
| 620 | unsigned long va) | 635 | unsigned long va) |
| 621 | { | 636 | { |
| 622 | struct kvm *kvm = vcpu->kvm; | 637 | struct kvm *kvm = vcpu->kvm; |
| 623 | unsigned long *hpte; | 638 | __be64 *hpte; |
| 624 | struct revmap_entry *rev; | 639 | struct revmap_entry *rev; |
| 625 | unsigned long v, r, rb, mask, bits; | 640 | unsigned long v, r, rb, mask, bits; |
| 641 | u64 pte; | ||
| 626 | 642 | ||
| 627 | if (pte_index >= kvm->arch.hpt_npte) | 643 | if (pte_index >= kvm->arch.hpt_npte) |
| 628 | return H_PARAMETER; | 644 | return H_PARAMETER; |
| 629 | 645 | ||
| 630 | hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); | 646 | hpte = (__be64 *)(kvm->arch.hpt_virt + (pte_index << 4)); |
| 631 | while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) | 647 | while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) |
| 632 | cpu_relax(); | 648 | cpu_relax(); |
| 633 | if ((hpte[0] & (HPTE_V_ABSENT | HPTE_V_VALID)) == 0 || | 649 | pte = be64_to_cpu(hpte[0]); |
| 634 | ((flags & H_AVPN) && (hpte[0] & ~0x7fUL) != avpn)) { | 650 | if ((pte & (HPTE_V_ABSENT | HPTE_V_VALID)) == 0 || |
| 635 | hpte[0] &= ~HPTE_V_HVLOCK; | 651 | ((flags & H_AVPN) && (pte & ~0x7fUL) != avpn)) { |
| 652 | hpte[0] &= ~cpu_to_be64(HPTE_V_HVLOCK); | ||
| 636 | return H_NOT_FOUND; | 653 | return H_NOT_FOUND; |
| 637 | } | 654 | } |
| 638 | 655 | ||
| 639 | v = hpte[0]; | 656 | v = pte; |
| 640 | bits = (flags << 55) & HPTE_R_PP0; | 657 | bits = (flags << 55) & HPTE_R_PP0; |
| 641 | bits |= (flags << 48) & HPTE_R_KEY_HI; | 658 | bits |= (flags << 48) & HPTE_R_KEY_HI; |
| 642 | bits |= flags & (HPTE_R_PP | HPTE_R_N | HPTE_R_KEY_LO); | 659 | bits |= flags & (HPTE_R_PP | HPTE_R_N | HPTE_R_KEY_LO); |
| @@ -650,12 +667,12 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags, | |||
| 650 | rev->guest_rpte = r; | 667 | rev->guest_rpte = r; |
| 651 | note_hpte_modification(kvm, rev); | 668 | note_hpte_modification(kvm, rev); |
| 652 | } | 669 | } |
| 653 | r = (hpte[1] & ~mask) | bits; | 670 | r = (be64_to_cpu(hpte[1]) & ~mask) | bits; |
| 654 | 671 | ||
| 655 | /* Update HPTE */ | 672 | /* Update HPTE */ |
| 656 | if (v & HPTE_V_VALID) { | 673 | if (v & HPTE_V_VALID) { |
| 657 | rb = compute_tlbie_rb(v, r, pte_index); | 674 | rb = compute_tlbie_rb(v, r, pte_index); |
| 658 | hpte[0] = v & ~HPTE_V_VALID; | 675 | hpte[0] = cpu_to_be64(v & ~HPTE_V_VALID); |
| 659 | do_tlbies(kvm, &rb, 1, global_invalidates(kvm, flags), true); | 676 | do_tlbies(kvm, &rb, 1, global_invalidates(kvm, flags), true); |
| 660 | /* | 677 | /* |
| 661 | * If the host has this page as readonly but the guest | 678 | * If the host has this page as readonly but the guest |
| @@ -681,9 +698,9 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags, | |||
| 681 | } | 698 | } |
| 682 | } | 699 | } |
| 683 | } | 700 | } |
| 684 | hpte[1] = r; | 701 | hpte[1] = cpu_to_be64(r); |
| 685 | eieio(); | 702 | eieio(); |
| 686 | hpte[0] = v & ~HPTE_V_HVLOCK; | 703 | hpte[0] = cpu_to_be64(v & ~HPTE_V_HVLOCK); |
| 687 | asm volatile("ptesync" : : : "memory"); | 704 | asm volatile("ptesync" : : : "memory"); |
| 688 | return H_SUCCESS; | 705 | return H_SUCCESS; |
| 689 | } | 706 | } |
| @@ -692,7 +709,8 @@ long kvmppc_h_read(struct kvm_vcpu *vcpu, unsigned long flags, | |||
| 692 | unsigned long pte_index) | 709 | unsigned long pte_index) |
| 693 | { | 710 | { |
| 694 | struct kvm *kvm = vcpu->kvm; | 711 | struct kvm *kvm = vcpu->kvm; |
| 695 | unsigned long *hpte, v, r; | 712 | __be64 *hpte; |
| 713 | unsigned long v, r; | ||
| 696 | int i, n = 1; | 714 | int i, n = 1; |
| 697 | struct revmap_entry *rev = NULL; | 715 | struct revmap_entry *rev = NULL; |
| 698 | 716 | ||
| @@ -704,9 +722,9 @@ long kvmppc_h_read(struct kvm_vcpu *vcpu, unsigned long flags, | |||
| 704 | } | 722 | } |
| 705 | rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]); | 723 | rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]); |
| 706 | for (i = 0; i < n; ++i, ++pte_index) { | 724 | for (i = 0; i < n; ++i, ++pte_index) { |
| 707 | hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); | 725 | hpte = (__be64 *)(kvm->arch.hpt_virt + (pte_index << 4)); |
| 708 | v = hpte[0] & ~HPTE_V_HVLOCK; | 726 | v = be64_to_cpu(hpte[0]) & ~HPTE_V_HVLOCK; |
| 709 | r = hpte[1]; | 727 | r = be64_to_cpu(hpte[1]); |
| 710 | if (v & HPTE_V_ABSENT) { | 728 | if (v & HPTE_V_ABSENT) { |
| 711 | v &= ~HPTE_V_ABSENT; | 729 | v &= ~HPTE_V_ABSENT; |
| 712 | v |= HPTE_V_VALID; | 730 | v |= HPTE_V_VALID; |
| @@ -721,25 +739,27 @@ long kvmppc_h_read(struct kvm_vcpu *vcpu, unsigned long flags, | |||
| 721 | return H_SUCCESS; | 739 | return H_SUCCESS; |
| 722 | } | 740 | } |
| 723 | 741 | ||
| 724 | void kvmppc_invalidate_hpte(struct kvm *kvm, unsigned long *hptep, | 742 | void kvmppc_invalidate_hpte(struct kvm *kvm, __be64 *hptep, |
| 725 | unsigned long pte_index) | 743 | unsigned long pte_index) |
| 726 | { | 744 | { |
| 727 | unsigned long rb; | 745 | unsigned long rb; |
| 728 | 746 | ||
| 729 | hptep[0] &= ~HPTE_V_VALID; | 747 | hptep[0] &= ~cpu_to_be64(HPTE_V_VALID); |
| 730 | rb = compute_tlbie_rb(hptep[0], hptep[1], pte_index); | 748 | rb = compute_tlbie_rb(be64_to_cpu(hptep[0]), be64_to_cpu(hptep[1]), |
| 749 | pte_index); | ||
| 731 | do_tlbies(kvm, &rb, 1, 1, true); | 750 | do_tlbies(kvm, &rb, 1, 1, true); |
| 732 | } | 751 | } |
| 733 | EXPORT_SYMBOL_GPL(kvmppc_invalidate_hpte); | 752 | EXPORT_SYMBOL_GPL(kvmppc_invalidate_hpte); |
| 734 | 753 | ||
| 735 | void kvmppc_clear_ref_hpte(struct kvm *kvm, unsigned long *hptep, | 754 | void kvmppc_clear_ref_hpte(struct kvm *kvm, __be64 *hptep, |
| 736 | unsigned long pte_index) | 755 | unsigned long pte_index) |
| 737 | { | 756 | { |
| 738 | unsigned long rb; | 757 | unsigned long rb; |
| 739 | unsigned char rbyte; | 758 | unsigned char rbyte; |
| 740 | 759 | ||
| 741 | rb = compute_tlbie_rb(hptep[0], hptep[1], pte_index); | 760 | rb = compute_tlbie_rb(be64_to_cpu(hptep[0]), be64_to_cpu(hptep[1]), |
| 742 | rbyte = (hptep[1] & ~HPTE_R_R) >> 8; | 761 | pte_index); |
| 762 | rbyte = (be64_to_cpu(hptep[1]) & ~HPTE_R_R) >> 8; | ||
| 743 | /* modify only the second-last byte, which contains the ref bit */ | 763 | /* modify only the second-last byte, which contains the ref bit */ |
| 744 | *((char *)hptep + 14) = rbyte; | 764 | *((char *)hptep + 14) = rbyte; |
| 745 | do_tlbies(kvm, &rb, 1, 1, false); | 765 | do_tlbies(kvm, &rb, 1, 1, false); |
| @@ -765,7 +785,7 @@ long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v, | |||
| 765 | unsigned long somask; | 785 | unsigned long somask; |
| 766 | unsigned long vsid, hash; | 786 | unsigned long vsid, hash; |
| 767 | unsigned long avpn; | 787 | unsigned long avpn; |
| 768 | unsigned long *hpte; | 788 | __be64 *hpte; |
| 769 | unsigned long mask, val; | 789 | unsigned long mask, val; |
| 770 | unsigned long v, r; | 790 | unsigned long v, r; |
| 771 | 791 | ||
| @@ -797,11 +817,11 @@ long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v, | |||
| 797 | val |= avpn; | 817 | val |= avpn; |
| 798 | 818 | ||
| 799 | for (;;) { | 819 | for (;;) { |
| 800 | hpte = (unsigned long *)(kvm->arch.hpt_virt + (hash << 7)); | 820 | hpte = (__be64 *)(kvm->arch.hpt_virt + (hash << 7)); |
| 801 | 821 | ||
| 802 | for (i = 0; i < 16; i += 2) { | 822 | for (i = 0; i < 16; i += 2) { |
| 803 | /* Read the PTE racily */ | 823 | /* Read the PTE racily */ |
| 804 | v = hpte[i] & ~HPTE_V_HVLOCK; | 824 | v = be64_to_cpu(hpte[i]) & ~HPTE_V_HVLOCK; |
| 805 | 825 | ||
| 806 | /* Check valid/absent, hash, segment size and AVPN */ | 826 | /* Check valid/absent, hash, segment size and AVPN */ |
| 807 | if (!(v & valid) || (v & mask) != val) | 827 | if (!(v & valid) || (v & mask) != val) |
| @@ -810,8 +830,8 @@ long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v, | |||
| 810 | /* Lock the PTE and read it under the lock */ | 830 | /* Lock the PTE and read it under the lock */ |
| 811 | while (!try_lock_hpte(&hpte[i], HPTE_V_HVLOCK)) | 831 | while (!try_lock_hpte(&hpte[i], HPTE_V_HVLOCK)) |
| 812 | cpu_relax(); | 832 | cpu_relax(); |
| 813 | v = hpte[i] & ~HPTE_V_HVLOCK; | 833 | v = be64_to_cpu(hpte[i]) & ~HPTE_V_HVLOCK; |
| 814 | r = hpte[i+1]; | 834 | r = be64_to_cpu(hpte[i+1]); |
| 815 | 835 | ||
| 816 | /* | 836 | /* |
| 817 | * Check the HPTE again, including base page size | 837 | * Check the HPTE again, including base page size |
| @@ -822,7 +842,7 @@ long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v, | |||
| 822 | return (hash << 3) + (i >> 1); | 842 | return (hash << 3) + (i >> 1); |
| 823 | 843 | ||
| 824 | /* Unlock and move on */ | 844 | /* Unlock and move on */ |
| 825 | hpte[i] = v; | 845 | hpte[i] = cpu_to_be64(v); |
| 826 | } | 846 | } |
| 827 | 847 | ||
| 828 | if (val & HPTE_V_SECONDARY) | 848 | if (val & HPTE_V_SECONDARY) |
| @@ -851,7 +871,7 @@ long kvmppc_hpte_hv_fault(struct kvm_vcpu *vcpu, unsigned long addr, | |||
| 851 | struct kvm *kvm = vcpu->kvm; | 871 | struct kvm *kvm = vcpu->kvm; |
| 852 | long int index; | 872 | long int index; |
| 853 | unsigned long v, r, gr; | 873 | unsigned long v, r, gr; |
| 854 | unsigned long *hpte; | 874 | __be64 *hpte; |
| 855 | unsigned long valid; | 875 | unsigned long valid; |
| 856 | struct revmap_entry *rev; | 876 | struct revmap_entry *rev; |
| 857 | unsigned long pp, key; | 877 | unsigned long pp, key; |
| @@ -867,9 +887,9 @@ long kvmppc_hpte_hv_fault(struct kvm_vcpu *vcpu, unsigned long addr, | |||
| 867 | return status; /* there really was no HPTE */ | 887 | return status; /* there really was no HPTE */ |
| 868 | return 0; /* for prot fault, HPTE disappeared */ | 888 | return 0; /* for prot fault, HPTE disappeared */ |
| 869 | } | 889 | } |
| 870 | hpte = (unsigned long *)(kvm->arch.hpt_virt + (index << 4)); | 890 | hpte = (__be64 *)(kvm->arch.hpt_virt + (index << 4)); |
| 871 | v = hpte[0] & ~HPTE_V_HVLOCK; | 891 | v = be64_to_cpu(hpte[0]) & ~HPTE_V_HVLOCK; |
| 872 | r = hpte[1]; | 892 | r = be64_to_cpu(hpte[1]); |
| 873 | rev = real_vmalloc_addr(&kvm->arch.revmap[index]); | 893 | rev = real_vmalloc_addr(&kvm->arch.revmap[index]); |
| 874 | gr = rev->guest_rpte; | 894 | gr = rev->guest_rpte; |
| 875 | 895 | ||
diff --git a/arch/powerpc/kvm/book3s_hv_rm_xics.c b/arch/powerpc/kvm/book3s_hv_rm_xics.c index b4b0082f761c..3ee38e6e884f 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_xics.c +++ b/arch/powerpc/kvm/book3s_hv_rm_xics.c | |||
| @@ -401,6 +401,11 @@ int kvmppc_rm_h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr) | |||
| 401 | icp->rm_action |= XICS_RM_REJECT; | 401 | icp->rm_action |= XICS_RM_REJECT; |
| 402 | icp->rm_reject = irq; | 402 | icp->rm_reject = irq; |
| 403 | } | 403 | } |
| 404 | |||
| 405 | if (!hlist_empty(&vcpu->kvm->irq_ack_notifier_list)) { | ||
| 406 | icp->rm_action |= XICS_RM_NOTIFY_EOI; | ||
| 407 | icp->rm_eoied_irq = irq; | ||
| 408 | } | ||
| 404 | bail: | 409 | bail: |
| 405 | return check_too_hard(xics, icp); | 410 | return check_too_hard(xics, icp); |
| 406 | } | 411 | } |
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 7faf8fd05738..f0c4db7704c3 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S | |||
| @@ -32,10 +32,6 @@ | |||
| 32 | 32 | ||
| 33 | #define VCPU_GPRS_TM(reg) (((reg) * ULONG_SIZE) + VCPU_GPR_TM) | 33 | #define VCPU_GPRS_TM(reg) (((reg) * ULONG_SIZE) + VCPU_GPR_TM) |
| 34 | 34 | ||
| 35 | #ifdef __LITTLE_ENDIAN__ | ||
| 36 | #error Need to fix lppaca and SLB shadow accesses in little endian mode | ||
| 37 | #endif | ||
| 38 | |||
| 39 | /* Values in HSTATE_NAPPING(r13) */ | 35 | /* Values in HSTATE_NAPPING(r13) */ |
| 40 | #define NAPPING_CEDE 1 | 36 | #define NAPPING_CEDE 1 |
| 41 | #define NAPPING_NOVCPU 2 | 37 | #define NAPPING_NOVCPU 2 |
| @@ -601,9 +597,10 @@ kvmppc_got_guest: | |||
| 601 | ld r3, VCPU_VPA(r4) | 597 | ld r3, VCPU_VPA(r4) |
| 602 | cmpdi r3, 0 | 598 | cmpdi r3, 0 |
| 603 | beq 25f | 599 | beq 25f |
| 604 | lwz r5, LPPACA_YIELDCOUNT(r3) | 600 | li r6, LPPACA_YIELDCOUNT |
| 601 | LWZX_BE r5, r3, r6 | ||
| 605 | addi r5, r5, 1 | 602 | addi r5, r5, 1 |
| 606 | stw r5, LPPACA_YIELDCOUNT(r3) | 603 | STWX_BE r5, r3, r6 |
| 607 | li r6, 1 | 604 | li r6, 1 |
| 608 | stb r6, VCPU_VPA_DIRTY(r4) | 605 | stb r6, VCPU_VPA_DIRTY(r4) |
| 609 | 25: | 606 | 25: |
| @@ -677,9 +674,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_TM) | |||
| 677 | 674 | ||
| 678 | mr r31, r4 | 675 | mr r31, r4 |
| 679 | addi r3, r31, VCPU_FPRS_TM | 676 | addi r3, r31, VCPU_FPRS_TM |
| 680 | bl .load_fp_state | 677 | bl load_fp_state |
| 681 | addi r3, r31, VCPU_VRS_TM | 678 | addi r3, r31, VCPU_VRS_TM |
| 682 | bl .load_vr_state | 679 | bl load_vr_state |
| 683 | mr r4, r31 | 680 | mr r4, r31 |
| 684 | lwz r7, VCPU_VRSAVE_TM(r4) | 681 | lwz r7, VCPU_VRSAVE_TM(r4) |
| 685 | mtspr SPRN_VRSAVE, r7 | 682 | mtspr SPRN_VRSAVE, r7 |
| @@ -1423,9 +1420,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_TM) | |||
| 1423 | 1420 | ||
| 1424 | /* Save FP/VSX. */ | 1421 | /* Save FP/VSX. */ |
| 1425 | addi r3, r9, VCPU_FPRS_TM | 1422 | addi r3, r9, VCPU_FPRS_TM |
| 1426 | bl .store_fp_state | 1423 | bl store_fp_state |
| 1427 | addi r3, r9, VCPU_VRS_TM | 1424 | addi r3, r9, VCPU_VRS_TM |
| 1428 | bl .store_vr_state | 1425 | bl store_vr_state |
| 1429 | mfspr r6, SPRN_VRSAVE | 1426 | mfspr r6, SPRN_VRSAVE |
| 1430 | stw r6, VCPU_VRSAVE_TM(r9) | 1427 | stw r6, VCPU_VRSAVE_TM(r9) |
| 1431 | 1: | 1428 | 1: |
| @@ -1448,9 +1445,10 @@ END_FTR_SECTION_IFCLR(CPU_FTR_TM) | |||
| 1448 | ld r8, VCPU_VPA(r9) /* do they have a VPA? */ | 1445 | ld r8, VCPU_VPA(r9) /* do they have a VPA? */ |
| 1449 | cmpdi r8, 0 | 1446 | cmpdi r8, 0 |
| 1450 | beq 25f | 1447 | beq 25f |
| 1451 | lwz r3, LPPACA_YIELDCOUNT(r8) | 1448 | li r4, LPPACA_YIELDCOUNT |
| 1449 | LWZX_BE r3, r8, r4 | ||
| 1452 | addi r3, r3, 1 | 1450 | addi r3, r3, 1 |
| 1453 | stw r3, LPPACA_YIELDCOUNT(r8) | 1451 | STWX_BE r3, r8, r4 |
| 1454 | li r3, 1 | 1452 | li r3, 1 |
| 1455 | stb r3, VCPU_VPA_DIRTY(r9) | 1453 | stb r3, VCPU_VPA_DIRTY(r9) |
| 1456 | 25: | 1454 | 25: |
| @@ -1763,8 +1761,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) | |||
| 1763 | 33: ld r8,PACA_SLBSHADOWPTR(r13) | 1761 | 33: ld r8,PACA_SLBSHADOWPTR(r13) |
| 1764 | 1762 | ||
| 1765 | .rept SLB_NUM_BOLTED | 1763 | .rept SLB_NUM_BOLTED |
| 1766 | ld r5,SLBSHADOW_SAVEAREA(r8) | 1764 | li r3, SLBSHADOW_SAVEAREA |
| 1767 | ld r6,SLBSHADOW_SAVEAREA+8(r8) | 1765 | LDX_BE r5, r8, r3 |
| 1766 | addi r3, r3, 8 | ||
| 1767 | LDX_BE r6, r8, r3 | ||
| 1768 | andis. r7,r5,SLB_ESID_V@h | 1768 | andis. r7,r5,SLB_ESID_V@h |
| 1769 | beq 1f | 1769 | beq 1f |
| 1770 | slbmte r6,r5 | 1770 | slbmte r6,r5 |
| @@ -1915,12 +1915,23 @@ hcall_try_real_mode: | |||
| 1915 | clrrdi r3,r3,2 | 1915 | clrrdi r3,r3,2 |
| 1916 | cmpldi r3,hcall_real_table_end - hcall_real_table | 1916 | cmpldi r3,hcall_real_table_end - hcall_real_table |
| 1917 | bge guest_exit_cont | 1917 | bge guest_exit_cont |
| 1918 | /* See if this hcall is enabled for in-kernel handling */ | ||
| 1919 | ld r4, VCPU_KVM(r9) | ||
| 1920 | srdi r0, r3, 8 /* r0 = (r3 / 4) >> 6 */ | ||
| 1921 | sldi r0, r0, 3 /* index into kvm->arch.enabled_hcalls[] */ | ||
| 1922 | add r4, r4, r0 | ||
| 1923 | ld r0, KVM_ENABLED_HCALLS(r4) | ||
| 1924 | rlwinm r4, r3, 32-2, 0x3f /* r4 = (r3 / 4) & 0x3f */ | ||
| 1925 | srd r0, r0, r4 | ||
| 1926 | andi. r0, r0, 1 | ||
| 1927 | beq guest_exit_cont | ||
| 1928 | /* Get pointer to handler, if any, and call it */ | ||
| 1918 | LOAD_REG_ADDR(r4, hcall_real_table) | 1929 | LOAD_REG_ADDR(r4, hcall_real_table) |
| 1919 | lwax r3,r3,r4 | 1930 | lwax r3,r3,r4 |
| 1920 | cmpwi r3,0 | 1931 | cmpwi r3,0 |
| 1921 | beq guest_exit_cont | 1932 | beq guest_exit_cont |
| 1922 | add r3,r3,r4 | 1933 | add r12,r3,r4 |
| 1923 | mtctr r3 | 1934 | mtctr r12 |
| 1924 | mr r3,r9 /* get vcpu pointer */ | 1935 | mr r3,r9 /* get vcpu pointer */ |
| 1925 | ld r4,VCPU_GPR(R4)(r9) | 1936 | ld r4,VCPU_GPR(R4)(r9) |
| 1926 | bctrl | 1937 | bctrl |
| @@ -2037,6 +2048,7 @@ hcall_real_table: | |||
| 2037 | .long 0 /* 0x12c */ | 2048 | .long 0 /* 0x12c */ |
| 2038 | .long 0 /* 0x130 */ | 2049 | .long 0 /* 0x130 */ |
| 2039 | .long DOTSYM(kvmppc_h_set_xdabr) - hcall_real_table | 2050 | .long DOTSYM(kvmppc_h_set_xdabr) - hcall_real_table |
| 2051 | .globl hcall_real_table_end | ||
| 2040 | hcall_real_table_end: | 2052 | hcall_real_table_end: |
| 2041 | 2053 | ||
| 2042 | ignore_hdec: | 2054 | ignore_hdec: |
| @@ -2344,7 +2356,18 @@ kvmppc_read_intr: | |||
| 2344 | cmpdi r6, 0 | 2356 | cmpdi r6, 0 |
| 2345 | beq- 1f | 2357 | beq- 1f |
| 2346 | lwzcix r0, r6, r7 | 2358 | lwzcix r0, r6, r7 |
| 2347 | rlwinm. r3, r0, 0, 0xffffff | 2359 | /* |
| 2360 | * Save XIRR for later. Since we get in in reverse endian on LE | ||
| 2361 | * systems, save it byte reversed and fetch it back in host endian. | ||
| 2362 | */ | ||
| 2363 | li r3, HSTATE_SAVED_XIRR | ||
| 2364 | STWX_BE r0, r3, r13 | ||
| 2365 | #ifdef __LITTLE_ENDIAN__ | ||
| 2366 | lwz r3, HSTATE_SAVED_XIRR(r13) | ||
| 2367 | #else | ||
| 2368 | mr r3, r0 | ||
| 2369 | #endif | ||
| 2370 | rlwinm. r3, r3, 0, 0xffffff | ||
| 2348 | sync | 2371 | sync |
| 2349 | beq 1f /* if nothing pending in the ICP */ | 2372 | beq 1f /* if nothing pending in the ICP */ |
| 2350 | 2373 | ||
| @@ -2376,10 +2399,9 @@ kvmppc_read_intr: | |||
| 2376 | li r3, -1 | 2399 | li r3, -1 |
| 2377 | 1: blr | 2400 | 1: blr |
| 2378 | 2401 | ||
| 2379 | 42: /* It's not an IPI and it's for the host, stash it in the PACA | 2402 | 42: /* It's not an IPI and it's for the host. We saved a copy of XIRR in |
| 2380 | * before exit, it will be picked up by the host ICP driver | 2403 | * the PACA earlier, it will be picked up by the host ICP driver |
| 2381 | */ | 2404 | */ |
| 2382 | stw r0, HSTATE_SAVED_XIRR(r13) | ||
| 2383 | li r3, 1 | 2405 | li r3, 1 |
| 2384 | b 1b | 2406 | b 1b |
| 2385 | 2407 | ||
| @@ -2414,11 +2436,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) | |||
| 2414 | mtmsrd r8 | 2436 | mtmsrd r8 |
| 2415 | isync | 2437 | isync |
| 2416 | addi r3,r3,VCPU_FPRS | 2438 | addi r3,r3,VCPU_FPRS |
| 2417 | bl .store_fp_state | 2439 | bl store_fp_state |
| 2418 | #ifdef CONFIG_ALTIVEC | 2440 | #ifdef CONFIG_ALTIVEC |
| 2419 | BEGIN_FTR_SECTION | 2441 | BEGIN_FTR_SECTION |
| 2420 | addi r3,r31,VCPU_VRS | 2442 | addi r3,r31,VCPU_VRS |
| 2421 | bl .store_vr_state | 2443 | bl store_vr_state |
| 2422 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | 2444 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) |
| 2423 | #endif | 2445 | #endif |
| 2424 | mfspr r6,SPRN_VRSAVE | 2446 | mfspr r6,SPRN_VRSAVE |
| @@ -2450,11 +2472,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) | |||
| 2450 | mtmsrd r8 | 2472 | mtmsrd r8 |
| 2451 | isync | 2473 | isync |
| 2452 | addi r3,r4,VCPU_FPRS | 2474 | addi r3,r4,VCPU_FPRS |
| 2453 | bl .load_fp_state | 2475 | bl load_fp_state |
| 2454 | #ifdef CONFIG_ALTIVEC | 2476 | #ifdef CONFIG_ALTIVEC |
| 2455 | BEGIN_FTR_SECTION | 2477 | BEGIN_FTR_SECTION |
| 2456 | addi r3,r31,VCPU_VRS | 2478 | addi r3,r31,VCPU_VRS |
| 2457 | bl .load_vr_state | 2479 | bl load_vr_state |
| 2458 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | 2480 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) |
| 2459 | #endif | 2481 | #endif |
| 2460 | lwz r7,VCPU_VRSAVE(r31) | 2482 | lwz r7,VCPU_VRSAVE(r31) |
diff --git a/arch/powerpc/kvm/book3s_paired_singles.c b/arch/powerpc/kvm/book3s_paired_singles.c index 6c8011fd57e6..bfb8035314e3 100644 --- a/arch/powerpc/kvm/book3s_paired_singles.c +++ b/arch/powerpc/kvm/book3s_paired_singles.c | |||
| @@ -639,26 +639,36 @@ static int kvmppc_ps_one_in(struct kvm_vcpu *vcpu, bool rc, | |||
| 639 | 639 | ||
| 640 | int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu) | 640 | int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu) |
| 641 | { | 641 | { |
| 642 | u32 inst = kvmppc_get_last_inst(vcpu); | 642 | u32 inst; |
| 643 | enum emulation_result emulated = EMULATE_DONE; | 643 | enum emulation_result emulated = EMULATE_DONE; |
| 644 | int ax_rd, ax_ra, ax_rb, ax_rc; | ||
| 645 | short full_d; | ||
| 646 | u64 *fpr_d, *fpr_a, *fpr_b, *fpr_c; | ||
| 644 | 647 | ||
| 645 | int ax_rd = inst_get_field(inst, 6, 10); | 648 | bool rcomp; |
| 646 | int ax_ra = inst_get_field(inst, 11, 15); | 649 | u32 cr; |
| 647 | int ax_rb = inst_get_field(inst, 16, 20); | ||
| 648 | int ax_rc = inst_get_field(inst, 21, 25); | ||
| 649 | short full_d = inst_get_field(inst, 16, 31); | ||
| 650 | |||
| 651 | u64 *fpr_d = &VCPU_FPR(vcpu, ax_rd); | ||
| 652 | u64 *fpr_a = &VCPU_FPR(vcpu, ax_ra); | ||
| 653 | u64 *fpr_b = &VCPU_FPR(vcpu, ax_rb); | ||
| 654 | u64 *fpr_c = &VCPU_FPR(vcpu, ax_rc); | ||
| 655 | |||
| 656 | bool rcomp = (inst & 1) ? true : false; | ||
| 657 | u32 cr = kvmppc_get_cr(vcpu); | ||
| 658 | #ifdef DEBUG | 650 | #ifdef DEBUG |
| 659 | int i; | 651 | int i; |
| 660 | #endif | 652 | #endif |
| 661 | 653 | ||
| 654 | emulated = kvmppc_get_last_inst(vcpu, INST_GENERIC, &inst); | ||
| 655 | if (emulated != EMULATE_DONE) | ||
| 656 | return emulated; | ||
| 657 | |||
| 658 | ax_rd = inst_get_field(inst, 6, 10); | ||
| 659 | ax_ra = inst_get_field(inst, 11, 15); | ||
| 660 | ax_rb = inst_get_field(inst, 16, 20); | ||
| 661 | ax_rc = inst_get_field(inst, 21, 25); | ||
| 662 | full_d = inst_get_field(inst, 16, 31); | ||
| 663 | |||
| 664 | fpr_d = &VCPU_FPR(vcpu, ax_rd); | ||
| 665 | fpr_a = &VCPU_FPR(vcpu, ax_ra); | ||
| 666 | fpr_b = &VCPU_FPR(vcpu, ax_rb); | ||
| 667 | fpr_c = &VCPU_FPR(vcpu, ax_rc); | ||
| 668 | |||
| 669 | rcomp = (inst & 1) ? true : false; | ||
| 670 | cr = kvmppc_get_cr(vcpu); | ||
| 671 | |||
| 662 | if (!kvmppc_inst_is_paired_single(vcpu, inst)) | 672 | if (!kvmppc_inst_is_paired_single(vcpu, inst)) |
| 663 | return EMULATE_FAIL; | 673 | return EMULATE_FAIL; |
| 664 | 674 | ||
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index 8eef1e519077..faffb27badd9 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c | |||
| @@ -62,6 +62,35 @@ static void kvmppc_giveup_fac(struct kvm_vcpu *vcpu, ulong fac); | |||
| 62 | #define HW_PAGE_SIZE PAGE_SIZE | 62 | #define HW_PAGE_SIZE PAGE_SIZE |
| 63 | #endif | 63 | #endif |
| 64 | 64 | ||
| 65 | static bool kvmppc_is_split_real(struct kvm_vcpu *vcpu) | ||
| 66 | { | ||
| 67 | ulong msr = kvmppc_get_msr(vcpu); | ||
| 68 | return (msr & (MSR_IR|MSR_DR)) == MSR_DR; | ||
| 69 | } | ||
| 70 | |||
| 71 | static void kvmppc_fixup_split_real(struct kvm_vcpu *vcpu) | ||
| 72 | { | ||
| 73 | ulong msr = kvmppc_get_msr(vcpu); | ||
| 74 | ulong pc = kvmppc_get_pc(vcpu); | ||
| 75 | |||
| 76 | /* We are in DR only split real mode */ | ||
| 77 | if ((msr & (MSR_IR|MSR_DR)) != MSR_DR) | ||
| 78 | return; | ||
| 79 | |||
| 80 | /* We have not fixed up the guest already */ | ||
| 81 | if (vcpu->arch.hflags & BOOK3S_HFLAG_SPLIT_HACK) | ||
| 82 | return; | ||
| 83 | |||
| 84 | /* The code is in fixupable address space */ | ||
| 85 | if (pc & SPLIT_HACK_MASK) | ||
| 86 | return; | ||
| 87 | |||
| 88 | vcpu->arch.hflags |= BOOK3S_HFLAG_SPLIT_HACK; | ||
| 89 | kvmppc_set_pc(vcpu, pc | SPLIT_HACK_OFFS); | ||
| 90 | } | ||
| 91 | |||
| 92 | void kvmppc_unfixup_split_real(struct kvm_vcpu *vcpu); | ||
| 93 | |||
| 65 | static void kvmppc_core_vcpu_load_pr(struct kvm_vcpu *vcpu, int cpu) | 94 | static void kvmppc_core_vcpu_load_pr(struct kvm_vcpu *vcpu, int cpu) |
| 66 | { | 95 | { |
| 67 | #ifdef CONFIG_PPC_BOOK3S_64 | 96 | #ifdef CONFIG_PPC_BOOK3S_64 |
| @@ -71,10 +100,19 @@ static void kvmppc_core_vcpu_load_pr(struct kvm_vcpu *vcpu, int cpu) | |||
| 71 | svcpu->in_use = 0; | 100 | svcpu->in_use = 0; |
| 72 | svcpu_put(svcpu); | 101 | svcpu_put(svcpu); |
| 73 | #endif | 102 | #endif |
| 103 | |||
| 104 | /* Disable AIL if supported */ | ||
| 105 | if (cpu_has_feature(CPU_FTR_HVMODE) && | ||
| 106 | cpu_has_feature(CPU_FTR_ARCH_207S)) | ||
| 107 | mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~LPCR_AIL); | ||
| 108 | |||
| 74 | vcpu->cpu = smp_processor_id(); | 109 | vcpu->cpu = smp_processor_id(); |
| 75 | #ifdef CONFIG_PPC_BOOK3S_32 | 110 | #ifdef CONFIG_PPC_BOOK3S_32 |
| 76 | current->thread.kvm_shadow_vcpu = vcpu->arch.shadow_vcpu; | 111 | current->thread.kvm_shadow_vcpu = vcpu->arch.shadow_vcpu; |
| 77 | #endif | 112 | #endif |
| 113 | |||
| 114 | if (kvmppc_is_split_real(vcpu)) | ||
| 115 | kvmppc_fixup_split_real(vcpu); | ||
| 78 | } | 116 | } |
| 79 | 117 | ||
| 80 | static void kvmppc_core_vcpu_put_pr(struct kvm_vcpu *vcpu) | 118 | static void kvmppc_core_vcpu_put_pr(struct kvm_vcpu *vcpu) |
| @@ -89,8 +127,17 @@ static void kvmppc_core_vcpu_put_pr(struct kvm_vcpu *vcpu) | |||
| 89 | svcpu_put(svcpu); | 127 | svcpu_put(svcpu); |
| 90 | #endif | 128 | #endif |
| 91 | 129 | ||
| 130 | if (kvmppc_is_split_real(vcpu)) | ||
| 131 | kvmppc_unfixup_split_real(vcpu); | ||
| 132 | |||
| 92 | kvmppc_giveup_ext(vcpu, MSR_FP | MSR_VEC | MSR_VSX); | 133 | kvmppc_giveup_ext(vcpu, MSR_FP | MSR_VEC | MSR_VSX); |
| 93 | kvmppc_giveup_fac(vcpu, FSCR_TAR_LG); | 134 | kvmppc_giveup_fac(vcpu, FSCR_TAR_LG); |
| 135 | |||
| 136 | /* Enable AIL if supported */ | ||
| 137 | if (cpu_has_feature(CPU_FTR_HVMODE) && | ||
| 138 | cpu_has_feature(CPU_FTR_ARCH_207S)) | ||
| 139 | mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_AIL_3); | ||
| 140 | |||
| 94 | vcpu->cpu = -1; | 141 | vcpu->cpu = -1; |
| 95 | } | 142 | } |
| 96 | 143 | ||
| @@ -120,6 +167,14 @@ void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu, | |||
| 120 | #ifdef CONFIG_PPC_BOOK3S_64 | 167 | #ifdef CONFIG_PPC_BOOK3S_64 |
| 121 | svcpu->shadow_fscr = vcpu->arch.shadow_fscr; | 168 | svcpu->shadow_fscr = vcpu->arch.shadow_fscr; |
| 122 | #endif | 169 | #endif |
| 170 | /* | ||
| 171 | * Now also save the current time base value. We use this | ||
| 172 | * to find the guest purr and spurr value. | ||
| 173 | */ | ||
| 174 | vcpu->arch.entry_tb = get_tb(); | ||
| 175 | vcpu->arch.entry_vtb = get_vtb(); | ||
| 176 | if (cpu_has_feature(CPU_FTR_ARCH_207S)) | ||
| 177 | vcpu->arch.entry_ic = mfspr(SPRN_IC); | ||
| 123 | svcpu->in_use = true; | 178 | svcpu->in_use = true; |
| 124 | } | 179 | } |
| 125 | 180 | ||
| @@ -166,6 +221,14 @@ void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu, | |||
| 166 | #ifdef CONFIG_PPC_BOOK3S_64 | 221 | #ifdef CONFIG_PPC_BOOK3S_64 |
| 167 | vcpu->arch.shadow_fscr = svcpu->shadow_fscr; | 222 | vcpu->arch.shadow_fscr = svcpu->shadow_fscr; |
| 168 | #endif | 223 | #endif |
| 224 | /* | ||
| 225 | * Update purr and spurr using time base on exit. | ||
| 226 | */ | ||
| 227 | vcpu->arch.purr += get_tb() - vcpu->arch.entry_tb; | ||
| 228 | vcpu->arch.spurr += get_tb() - vcpu->arch.entry_tb; | ||
| 229 | vcpu->arch.vtb += get_vtb() - vcpu->arch.entry_vtb; | ||
| 230 | if (cpu_has_feature(CPU_FTR_ARCH_207S)) | ||
| 231 | vcpu->arch.ic += mfspr(SPRN_IC) - vcpu->arch.entry_ic; | ||
| 169 | svcpu->in_use = false; | 232 | svcpu->in_use = false; |
| 170 | 233 | ||
| 171 | out: | 234 | out: |
| @@ -294,6 +357,11 @@ static void kvmppc_set_msr_pr(struct kvm_vcpu *vcpu, u64 msr) | |||
| 294 | } | 357 | } |
| 295 | } | 358 | } |
| 296 | 359 | ||
| 360 | if (kvmppc_is_split_real(vcpu)) | ||
| 361 | kvmppc_fixup_split_real(vcpu); | ||
| 362 | else | ||
| 363 | kvmppc_unfixup_split_real(vcpu); | ||
| 364 | |||
| 297 | if ((kvmppc_get_msr(vcpu) & (MSR_PR|MSR_IR|MSR_DR)) != | 365 | if ((kvmppc_get_msr(vcpu) & (MSR_PR|MSR_IR|MSR_DR)) != |
| 298 | (old_msr & (MSR_PR|MSR_IR|MSR_DR))) { | 366 | (old_msr & (MSR_PR|MSR_IR|MSR_DR))) { |
| 299 | kvmppc_mmu_flush_segments(vcpu); | 367 | kvmppc_mmu_flush_segments(vcpu); |
| @@ -443,19 +511,19 @@ static void kvmppc_patch_dcbz(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte) | |||
| 443 | put_page(hpage); | 511 | put_page(hpage); |
| 444 | } | 512 | } |
| 445 | 513 | ||
| 446 | static int kvmppc_visible_gfn(struct kvm_vcpu *vcpu, gfn_t gfn) | 514 | static int kvmppc_visible_gpa(struct kvm_vcpu *vcpu, gpa_t gpa) |
| 447 | { | 515 | { |
| 448 | ulong mp_pa = vcpu->arch.magic_page_pa; | 516 | ulong mp_pa = vcpu->arch.magic_page_pa; |
| 449 | 517 | ||
| 450 | if (!(kvmppc_get_msr(vcpu) & MSR_SF)) | 518 | if (!(kvmppc_get_msr(vcpu) & MSR_SF)) |
| 451 | mp_pa = (uint32_t)mp_pa; | 519 | mp_pa = (uint32_t)mp_pa; |
| 452 | 520 | ||
| 453 | if (unlikely(mp_pa) && | 521 | gpa &= ~0xFFFULL; |
| 454 | unlikely((mp_pa & KVM_PAM) >> PAGE_SHIFT == gfn)) { | 522 | if (unlikely(mp_pa) && unlikely((mp_pa & KVM_PAM) == (gpa & KVM_PAM))) { |
| 455 | return 1; | 523 | return 1; |
| 456 | } | 524 | } |
| 457 | 525 | ||
| 458 | return kvm_is_visible_gfn(vcpu->kvm, gfn); | 526 | return kvm_is_visible_gfn(vcpu->kvm, gpa >> PAGE_SHIFT); |
| 459 | } | 527 | } |
| 460 | 528 | ||
| 461 | int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu, | 529 | int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu, |
| @@ -494,6 +562,11 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
| 494 | pte.vpage |= ((u64)VSID_REAL << (SID_SHIFT - 12)); | 562 | pte.vpage |= ((u64)VSID_REAL << (SID_SHIFT - 12)); |
| 495 | break; | 563 | break; |
| 496 | case MSR_DR: | 564 | case MSR_DR: |
| 565 | if (!data && | ||
| 566 | (vcpu->arch.hflags & BOOK3S_HFLAG_SPLIT_HACK) && | ||
| 567 | ((pte.raddr & SPLIT_HACK_MASK) == SPLIT_HACK_OFFS)) | ||
| 568 | pte.raddr &= ~SPLIT_HACK_MASK; | ||
| 569 | /* fall through */ | ||
| 497 | case MSR_IR: | 570 | case MSR_IR: |
| 498 | vcpu->arch.mmu.esid_to_vsid(vcpu, eaddr >> SID_SHIFT, &vsid); | 571 | vcpu->arch.mmu.esid_to_vsid(vcpu, eaddr >> SID_SHIFT, &vsid); |
| 499 | 572 | ||
| @@ -541,7 +614,7 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
| 541 | kvmppc_set_dar(vcpu, kvmppc_get_fault_dar(vcpu)); | 614 | kvmppc_set_dar(vcpu, kvmppc_get_fault_dar(vcpu)); |
| 542 | kvmppc_book3s_queue_irqprio(vcpu, vec + 0x80); | 615 | kvmppc_book3s_queue_irqprio(vcpu, vec + 0x80); |
| 543 | } else if (!is_mmio && | 616 | } else if (!is_mmio && |
| 544 | kvmppc_visible_gfn(vcpu, pte.raddr >> PAGE_SHIFT)) { | 617 | kvmppc_visible_gpa(vcpu, pte.raddr)) { |
| 545 | if (data && !(vcpu->arch.fault_dsisr & DSISR_NOHPTE)) { | 618 | if (data && !(vcpu->arch.fault_dsisr & DSISR_NOHPTE)) { |
| 546 | /* | 619 | /* |
| 547 | * There is already a host HPTE there, presumably | 620 | * There is already a host HPTE there, presumably |
| @@ -637,42 +710,6 @@ static void kvmppc_giveup_fac(struct kvm_vcpu *vcpu, ulong fac) | |||
| 637 | #endif | 710 | #endif |
| 638 | } | 711 | } |
| 639 | 712 | ||
| 640 | static int kvmppc_read_inst(struct kvm_vcpu *vcpu) | ||
| 641 | { | ||
| 642 | ulong srr0 = kvmppc_get_pc(vcpu); | ||
| 643 | u32 last_inst = kvmppc_get_last_inst(vcpu); | ||
| 644 | int ret; | ||
| 645 | |||
| 646 | ret = kvmppc_ld(vcpu, &srr0, sizeof(u32), &last_inst, false); | ||
| 647 | if (ret == -ENOENT) { | ||
| 648 | ulong msr = kvmppc_get_msr(vcpu); | ||
| 649 | |||
| 650 | msr = kvmppc_set_field(msr, 33, 33, 1); | ||
| 651 | msr = kvmppc_set_field(msr, 34, 36, 0); | ||
| 652 | msr = kvmppc_set_field(msr, 42, 47, 0); | ||
| 653 | kvmppc_set_msr_fast(vcpu, msr); | ||
| 654 | kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_INST_STORAGE); | ||
| 655 | return EMULATE_AGAIN; | ||
| 656 | } | ||
| 657 | |||
| 658 | return EMULATE_DONE; | ||
| 659 | } | ||
| 660 | |||
| 661 | static int kvmppc_check_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr) | ||
| 662 | { | ||
| 663 | |||
| 664 | /* Need to do paired single emulation? */ | ||
| 665 | if (!(vcpu->arch.hflags & BOOK3S_HFLAG_PAIRED_SINGLE)) | ||
| 666 | return EMULATE_DONE; | ||
| 667 | |||
| 668 | /* Read out the instruction */ | ||
| 669 | if (kvmppc_read_inst(vcpu) == EMULATE_DONE) | ||
| 670 | /* Need to emulate */ | ||
| 671 | return EMULATE_FAIL; | ||
| 672 | |||
| 673 | return EMULATE_AGAIN; | ||
| 674 | } | ||
| 675 | |||
| 676 | /* Handle external providers (FPU, Altivec, VSX) */ | 713 | /* Handle external providers (FPU, Altivec, VSX) */ |
| 677 | static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, | 714 | static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, |
| 678 | ulong msr) | 715 | ulong msr) |
| @@ -834,6 +871,15 @@ static int kvmppc_handle_fac(struct kvm_vcpu *vcpu, ulong fac) | |||
| 834 | 871 | ||
| 835 | return RESUME_GUEST; | 872 | return RESUME_GUEST; |
| 836 | } | 873 | } |
| 874 | |||
| 875 | void kvmppc_set_fscr(struct kvm_vcpu *vcpu, u64 fscr) | ||
| 876 | { | ||
| 877 | if ((vcpu->arch.fscr & FSCR_TAR) && !(fscr & FSCR_TAR)) { | ||
| 878 | /* TAR got dropped, drop it in shadow too */ | ||
| 879 | kvmppc_giveup_fac(vcpu, FSCR_TAR_LG); | ||
| 880 | } | ||
| 881 | vcpu->arch.fscr = fscr; | ||
| 882 | } | ||
| 837 | #endif | 883 | #endif |
| 838 | 884 | ||
| 839 | int kvmppc_handle_exit_pr(struct kvm_run *run, struct kvm_vcpu *vcpu, | 885 | int kvmppc_handle_exit_pr(struct kvm_run *run, struct kvm_vcpu *vcpu, |
| @@ -858,6 +904,9 @@ int kvmppc_handle_exit_pr(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
| 858 | ulong shadow_srr1 = vcpu->arch.shadow_srr1; | 904 | ulong shadow_srr1 = vcpu->arch.shadow_srr1; |
| 859 | vcpu->stat.pf_instruc++; | 905 | vcpu->stat.pf_instruc++; |
| 860 | 906 | ||
| 907 | if (kvmppc_is_split_real(vcpu)) | ||
| 908 | kvmppc_fixup_split_real(vcpu); | ||
| 909 | |||
| 861 | #ifdef CONFIG_PPC_BOOK3S_32 | 910 | #ifdef CONFIG_PPC_BOOK3S_32 |
| 862 | /* We set segments as unused segments when invalidating them. So | 911 | /* We set segments as unused segments when invalidating them. So |
| 863 | * treat the respective fault as segment fault. */ | 912 | * treat the respective fault as segment fault. */ |
| @@ -960,6 +1009,7 @@ int kvmppc_handle_exit_pr(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
| 960 | case BOOK3S_INTERRUPT_DECREMENTER: | 1009 | case BOOK3S_INTERRUPT_DECREMENTER: |
| 961 | case BOOK3S_INTERRUPT_HV_DECREMENTER: | 1010 | case BOOK3S_INTERRUPT_HV_DECREMENTER: |
| 962 | case BOOK3S_INTERRUPT_DOORBELL: | 1011 | case BOOK3S_INTERRUPT_DOORBELL: |
| 1012 | case BOOK3S_INTERRUPT_H_DOORBELL: | ||
| 963 | vcpu->stat.dec_exits++; | 1013 | vcpu->stat.dec_exits++; |
| 964 | r = RESUME_GUEST; | 1014 | r = RESUME_GUEST; |
| 965 | break; | 1015 | break; |
| @@ -977,15 +1027,24 @@ int kvmppc_handle_exit_pr(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
| 977 | { | 1027 | { |
| 978 | enum emulation_result er; | 1028 | enum emulation_result er; |
| 979 | ulong flags; | 1029 | ulong flags; |
| 1030 | u32 last_inst; | ||
| 1031 | int emul; | ||
| 980 | 1032 | ||
| 981 | program_interrupt: | 1033 | program_interrupt: |
| 982 | flags = vcpu->arch.shadow_srr1 & 0x1f0000ull; | 1034 | flags = vcpu->arch.shadow_srr1 & 0x1f0000ull; |
| 983 | 1035 | ||
| 1036 | emul = kvmppc_get_last_inst(vcpu, INST_GENERIC, &last_inst); | ||
| 1037 | if (emul != EMULATE_DONE) { | ||
| 1038 | r = RESUME_GUEST; | ||
| 1039 | break; | ||
| 1040 | } | ||
| 1041 | |||
| 984 | if (kvmppc_get_msr(vcpu) & MSR_PR) { | 1042 | if (kvmppc_get_msr(vcpu) & MSR_PR) { |
| 985 | #ifdef EXIT_DEBUG | 1043 | #ifdef EXIT_DEBUG |
| 986 | printk(KERN_INFO "Userspace triggered 0x700 exception at 0x%lx (0x%x)\n", kvmppc_get_pc(vcpu), kvmppc_get_last_inst(vcpu)); | 1044 | pr_info("Userspace triggered 0x700 exception at\n 0x%lx (0x%x)\n", |
| 1045 | kvmppc_get_pc(vcpu), last_inst); | ||
| 987 | #endif | 1046 | #endif |
| 988 | if ((kvmppc_get_last_inst(vcpu) & 0xff0007ff) != | 1047 | if ((last_inst & 0xff0007ff) != |
| 989 | (INS_DCBZ & 0xfffffff7)) { | 1048 | (INS_DCBZ & 0xfffffff7)) { |
| 990 | kvmppc_core_queue_program(vcpu, flags); | 1049 | kvmppc_core_queue_program(vcpu, flags); |
| 991 | r = RESUME_GUEST; | 1050 | r = RESUME_GUEST; |
| @@ -1004,7 +1063,7 @@ program_interrupt: | |||
| 1004 | break; | 1063 | break; |
| 1005 | case EMULATE_FAIL: | 1064 | case EMULATE_FAIL: |
| 1006 | printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n", | 1065 | printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n", |
| 1007 | __func__, kvmppc_get_pc(vcpu), kvmppc_get_last_inst(vcpu)); | 1066 | __func__, kvmppc_get_pc(vcpu), last_inst); |
| 1008 | kvmppc_core_queue_program(vcpu, flags); | 1067 | kvmppc_core_queue_program(vcpu, flags); |
| 1009 | r = RESUME_GUEST; | 1068 | r = RESUME_GUEST; |
| 1010 | break; | 1069 | break; |
| @@ -1021,8 +1080,23 @@ program_interrupt: | |||
| 1021 | break; | 1080 | break; |
| 1022 | } | 1081 | } |
| 1023 | case BOOK3S_INTERRUPT_SYSCALL: | 1082 | case BOOK3S_INTERRUPT_SYSCALL: |
| 1083 | { | ||
| 1084 | u32 last_sc; | ||
| 1085 | int emul; | ||
| 1086 | |||
| 1087 | /* Get last sc for papr */ | ||
| 1088 | if (vcpu->arch.papr_enabled) { | ||
| 1089 | /* The sc instuction points SRR0 to the next inst */ | ||
| 1090 | emul = kvmppc_get_last_inst(vcpu, INST_SC, &last_sc); | ||
| 1091 | if (emul != EMULATE_DONE) { | ||
| 1092 | kvmppc_set_pc(vcpu, kvmppc_get_pc(vcpu) - 4); | ||
| 1093 | r = RESUME_GUEST; | ||
| 1094 | break; | ||
| 1095 | } | ||
| 1096 | } | ||
| 1097 | |||
| 1024 | if (vcpu->arch.papr_enabled && | 1098 | if (vcpu->arch.papr_enabled && |
| 1025 | (kvmppc_get_last_sc(vcpu) == 0x44000022) && | 1099 | (last_sc == 0x44000022) && |
| 1026 | !(kvmppc_get_msr(vcpu) & MSR_PR)) { | 1100 | !(kvmppc_get_msr(vcpu) & MSR_PR)) { |
| 1027 | /* SC 1 papr hypercalls */ | 1101 | /* SC 1 papr hypercalls */ |
| 1028 | ulong cmd = kvmppc_get_gpr(vcpu, 3); | 1102 | ulong cmd = kvmppc_get_gpr(vcpu, 3); |
| @@ -1067,36 +1141,51 @@ program_interrupt: | |||
| 1067 | r = RESUME_GUEST; | 1141 | r = RESUME_GUEST; |
| 1068 | } | 1142 | } |
| 1069 | break; | 1143 | break; |
| 1144 | } | ||
| 1070 | case BOOK3S_INTERRUPT_FP_UNAVAIL: | 1145 | case BOOK3S_INTERRUPT_FP_UNAVAIL: |
| 1071 | case BOOK3S_INTERRUPT_ALTIVEC: | 1146 | case BOOK3S_INTERRUPT_ALTIVEC: |
| 1072 | case BOOK3S_INTERRUPT_VSX: | 1147 | case BOOK3S_INTERRUPT_VSX: |
| 1073 | { | 1148 | { |
| 1074 | int ext_msr = 0; | 1149 | int ext_msr = 0; |
| 1150 | int emul; | ||
| 1151 | u32 last_inst; | ||
| 1152 | |||
| 1153 | if (vcpu->arch.hflags & BOOK3S_HFLAG_PAIRED_SINGLE) { | ||
| 1154 | /* Do paired single instruction emulation */ | ||
| 1155 | emul = kvmppc_get_last_inst(vcpu, INST_GENERIC, | ||
| 1156 | &last_inst); | ||
| 1157 | if (emul == EMULATE_DONE) | ||
| 1158 | goto program_interrupt; | ||
| 1159 | else | ||
| 1160 | r = RESUME_GUEST; | ||
| 1075 | 1161 | ||
| 1076 | switch (exit_nr) { | 1162 | break; |
| 1077 | case BOOK3S_INTERRUPT_FP_UNAVAIL: ext_msr = MSR_FP; break; | ||
| 1078 | case BOOK3S_INTERRUPT_ALTIVEC: ext_msr = MSR_VEC; break; | ||
| 1079 | case BOOK3S_INTERRUPT_VSX: ext_msr = MSR_VSX; break; | ||
| 1080 | } | 1163 | } |
| 1081 | 1164 | ||
| 1082 | switch (kvmppc_check_ext(vcpu, exit_nr)) { | 1165 | /* Enable external provider */ |
| 1083 | case EMULATE_DONE: | 1166 | switch (exit_nr) { |
| 1084 | /* everything ok - let's enable the ext */ | 1167 | case BOOK3S_INTERRUPT_FP_UNAVAIL: |
| 1085 | r = kvmppc_handle_ext(vcpu, exit_nr, ext_msr); | 1168 | ext_msr = MSR_FP; |
| 1086 | break; | 1169 | break; |
| 1087 | case EMULATE_FAIL: | 1170 | |
| 1088 | /* we need to emulate this instruction */ | 1171 | case BOOK3S_INTERRUPT_ALTIVEC: |
| 1089 | goto program_interrupt; | 1172 | ext_msr = MSR_VEC; |
| 1090 | break; | 1173 | break; |
| 1091 | default: | 1174 | |
| 1092 | /* nothing to worry about - go again */ | 1175 | case BOOK3S_INTERRUPT_VSX: |
| 1176 | ext_msr = MSR_VSX; | ||
| 1093 | break; | 1177 | break; |
| 1094 | } | 1178 | } |
| 1179 | |||
| 1180 | r = kvmppc_handle_ext(vcpu, exit_nr, ext_msr); | ||
| 1095 | break; | 1181 | break; |
| 1096 | } | 1182 | } |
| 1097 | case BOOK3S_INTERRUPT_ALIGNMENT: | 1183 | case BOOK3S_INTERRUPT_ALIGNMENT: |
| 1098 | if (kvmppc_read_inst(vcpu) == EMULATE_DONE) { | 1184 | { |
| 1099 | u32 last_inst = kvmppc_get_last_inst(vcpu); | 1185 | u32 last_inst; |
| 1186 | int emul = kvmppc_get_last_inst(vcpu, INST_GENERIC, &last_inst); | ||
| 1187 | |||
| 1188 | if (emul == EMULATE_DONE) { | ||
| 1100 | u32 dsisr; | 1189 | u32 dsisr; |
| 1101 | u64 dar; | 1190 | u64 dar; |
| 1102 | 1191 | ||
| @@ -1110,6 +1199,7 @@ program_interrupt: | |||
| 1110 | } | 1199 | } |
| 1111 | r = RESUME_GUEST; | 1200 | r = RESUME_GUEST; |
| 1112 | break; | 1201 | break; |
| 1202 | } | ||
| 1113 | #ifdef CONFIG_PPC_BOOK3S_64 | 1203 | #ifdef CONFIG_PPC_BOOK3S_64 |
| 1114 | case BOOK3S_INTERRUPT_FAC_UNAVAIL: | 1204 | case BOOK3S_INTERRUPT_FAC_UNAVAIL: |
| 1115 | kvmppc_handle_fac(vcpu, vcpu->arch.shadow_fscr >> 56); | 1205 | kvmppc_handle_fac(vcpu, vcpu->arch.shadow_fscr >> 56); |
| @@ -1233,6 +1323,7 @@ static int kvmppc_get_one_reg_pr(struct kvm_vcpu *vcpu, u64 id, | |||
| 1233 | *val = get_reg_val(id, to_book3s(vcpu)->hior); | 1323 | *val = get_reg_val(id, to_book3s(vcpu)->hior); |
| 1234 | break; | 1324 | break; |
| 1235 | case KVM_REG_PPC_LPCR: | 1325 | case KVM_REG_PPC_LPCR: |
| 1326 | case KVM_REG_PPC_LPCR_64: | ||
| 1236 | /* | 1327 | /* |
| 1237 | * We are only interested in the LPCR_ILE bit | 1328 | * We are only interested in the LPCR_ILE bit |
| 1238 | */ | 1329 | */ |
| @@ -1268,6 +1359,7 @@ static int kvmppc_set_one_reg_pr(struct kvm_vcpu *vcpu, u64 id, | |||
| 1268 | to_book3s(vcpu)->hior_explicit = true; | 1359 | to_book3s(vcpu)->hior_explicit = true; |
| 1269 | break; | 1360 | break; |
| 1270 | case KVM_REG_PPC_LPCR: | 1361 | case KVM_REG_PPC_LPCR: |
| 1362 | case KVM_REG_PPC_LPCR_64: | ||
| 1271 | kvmppc_set_lpcr_pr(vcpu, set_reg_val(id, *val)); | 1363 | kvmppc_set_lpcr_pr(vcpu, set_reg_val(id, *val)); |
| 1272 | break; | 1364 | break; |
| 1273 | default: | 1365 | default: |
| @@ -1310,8 +1402,7 @@ static struct kvm_vcpu *kvmppc_core_vcpu_create_pr(struct kvm *kvm, | |||
| 1310 | p = __get_free_page(GFP_KERNEL|__GFP_ZERO); | 1402 | p = __get_free_page(GFP_KERNEL|__GFP_ZERO); |
| 1311 | if (!p) | 1403 | if (!p) |
| 1312 | goto uninit_vcpu; | 1404 | goto uninit_vcpu; |
| 1313 | /* the real shared page fills the last 4k of our page */ | 1405 | vcpu->arch.shared = (void *)p; |
| 1314 | vcpu->arch.shared = (void *)(p + PAGE_SIZE - 4096); | ||
| 1315 | #ifdef CONFIG_PPC_BOOK3S_64 | 1406 | #ifdef CONFIG_PPC_BOOK3S_64 |
| 1316 | /* Always start the shared struct in native endian mode */ | 1407 | /* Always start the shared struct in native endian mode */ |
| 1317 | #ifdef __BIG_ENDIAN__ | 1408 | #ifdef __BIG_ENDIAN__ |
| @@ -1568,6 +1659,11 @@ static int kvmppc_core_init_vm_pr(struct kvm *kvm) | |||
| 1568 | { | 1659 | { |
| 1569 | mutex_init(&kvm->arch.hpt_mutex); | 1660 | mutex_init(&kvm->arch.hpt_mutex); |
| 1570 | 1661 | ||
| 1662 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
| 1663 | /* Start out with the default set of hcalls enabled */ | ||
| 1664 | kvmppc_pr_init_default_hcalls(kvm); | ||
| 1665 | #endif | ||
| 1666 | |||
| 1571 | if (firmware_has_feature(FW_FEATURE_SET_MODE)) { | 1667 | if (firmware_has_feature(FW_FEATURE_SET_MODE)) { |
| 1572 | spin_lock(&kvm_global_user_count_lock); | 1668 | spin_lock(&kvm_global_user_count_lock); |
| 1573 | if (++kvm_global_user_count == 1) | 1669 | if (++kvm_global_user_count == 1) |
| @@ -1636,6 +1732,9 @@ static struct kvmppc_ops kvm_ops_pr = { | |||
| 1636 | .emulate_mfspr = kvmppc_core_emulate_mfspr_pr, | 1732 | .emulate_mfspr = kvmppc_core_emulate_mfspr_pr, |
| 1637 | .fast_vcpu_kick = kvm_vcpu_kick, | 1733 | .fast_vcpu_kick = kvm_vcpu_kick, |
| 1638 | .arch_vm_ioctl = kvm_arch_vm_ioctl_pr, | 1734 | .arch_vm_ioctl = kvm_arch_vm_ioctl_pr, |
| 1735 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
| 1736 | .hcall_implemented = kvmppc_hcall_impl_pr, | ||
| 1737 | #endif | ||
| 1639 | }; | 1738 | }; |
| 1640 | 1739 | ||
| 1641 | 1740 | ||
diff --git a/arch/powerpc/kvm/book3s_pr_papr.c b/arch/powerpc/kvm/book3s_pr_papr.c index 52a63bfe3f07..ce3c893d509b 100644 --- a/arch/powerpc/kvm/book3s_pr_papr.c +++ b/arch/powerpc/kvm/book3s_pr_papr.c | |||
| @@ -40,8 +40,9 @@ static int kvmppc_h_pr_enter(struct kvm_vcpu *vcpu) | |||
| 40 | { | 40 | { |
| 41 | long flags = kvmppc_get_gpr(vcpu, 4); | 41 | long flags = kvmppc_get_gpr(vcpu, 4); |
| 42 | long pte_index = kvmppc_get_gpr(vcpu, 5); | 42 | long pte_index = kvmppc_get_gpr(vcpu, 5); |
| 43 | unsigned long pteg[2 * 8]; | 43 | __be64 pteg[2 * 8]; |
| 44 | unsigned long pteg_addr, i, *hpte; | 44 | __be64 *hpte; |
| 45 | unsigned long pteg_addr, i; | ||
| 45 | long int ret; | 46 | long int ret; |
| 46 | 47 | ||
| 47 | i = pte_index & 7; | 48 | i = pte_index & 7; |
| @@ -93,8 +94,8 @@ static int kvmppc_h_pr_remove(struct kvm_vcpu *vcpu) | |||
| 93 | pteg = get_pteg_addr(vcpu, pte_index); | 94 | pteg = get_pteg_addr(vcpu, pte_index); |
| 94 | mutex_lock(&vcpu->kvm->arch.hpt_mutex); | 95 | mutex_lock(&vcpu->kvm->arch.hpt_mutex); |
| 95 | copy_from_user(pte, (void __user *)pteg, sizeof(pte)); | 96 | copy_from_user(pte, (void __user *)pteg, sizeof(pte)); |
| 96 | pte[0] = be64_to_cpu(pte[0]); | 97 | pte[0] = be64_to_cpu((__force __be64)pte[0]); |
| 97 | pte[1] = be64_to_cpu(pte[1]); | 98 | pte[1] = be64_to_cpu((__force __be64)pte[1]); |
| 98 | 99 | ||
| 99 | ret = H_NOT_FOUND; | 100 | ret = H_NOT_FOUND; |
| 100 | if ((pte[0] & HPTE_V_VALID) == 0 || | 101 | if ((pte[0] & HPTE_V_VALID) == 0 || |
| @@ -171,8 +172,8 @@ static int kvmppc_h_pr_bulk_remove(struct kvm_vcpu *vcpu) | |||
| 171 | 172 | ||
| 172 | pteg = get_pteg_addr(vcpu, tsh & H_BULK_REMOVE_PTEX); | 173 | pteg = get_pteg_addr(vcpu, tsh & H_BULK_REMOVE_PTEX); |
| 173 | copy_from_user(pte, (void __user *)pteg, sizeof(pte)); | 174 | copy_from_user(pte, (void __user *)pteg, sizeof(pte)); |
| 174 | pte[0] = be64_to_cpu(pte[0]); | 175 | pte[0] = be64_to_cpu((__force __be64)pte[0]); |
| 175 | pte[1] = be64_to_cpu(pte[1]); | 176 | pte[1] = be64_to_cpu((__force __be64)pte[1]); |
| 176 | 177 | ||
| 177 | /* tsl = AVPN */ | 178 | /* tsl = AVPN */ |
| 178 | flags = (tsh & H_BULK_REMOVE_FLAGS) >> 26; | 179 | flags = (tsh & H_BULK_REMOVE_FLAGS) >> 26; |
| @@ -211,8 +212,8 @@ static int kvmppc_h_pr_protect(struct kvm_vcpu *vcpu) | |||
| 211 | pteg = get_pteg_addr(vcpu, pte_index); | 212 | pteg = get_pteg_addr(vcpu, pte_index); |
| 212 | mutex_lock(&vcpu->kvm->arch.hpt_mutex); | 213 | mutex_lock(&vcpu->kvm->arch.hpt_mutex); |
| 213 | copy_from_user(pte, (void __user *)pteg, sizeof(pte)); | 214 | copy_from_user(pte, (void __user *)pteg, sizeof(pte)); |
| 214 | pte[0] = be64_to_cpu(pte[0]); | 215 | pte[0] = be64_to_cpu((__force __be64)pte[0]); |
| 215 | pte[1] = be64_to_cpu(pte[1]); | 216 | pte[1] = be64_to_cpu((__force __be64)pte[1]); |
| 216 | 217 | ||
| 217 | ret = H_NOT_FOUND; | 218 | ret = H_NOT_FOUND; |
| 218 | if ((pte[0] & HPTE_V_VALID) == 0 || | 219 | if ((pte[0] & HPTE_V_VALID) == 0 || |
| @@ -231,8 +232,8 @@ static int kvmppc_h_pr_protect(struct kvm_vcpu *vcpu) | |||
| 231 | 232 | ||
| 232 | rb = compute_tlbie_rb(v, r, pte_index); | 233 | rb = compute_tlbie_rb(v, r, pte_index); |
| 233 | vcpu->arch.mmu.tlbie(vcpu, rb, rb & 1 ? true : false); | 234 | vcpu->arch.mmu.tlbie(vcpu, rb, rb & 1 ? true : false); |
| 234 | pte[0] = cpu_to_be64(pte[0]); | 235 | pte[0] = (__force u64)cpu_to_be64(pte[0]); |
| 235 | pte[1] = cpu_to_be64(pte[1]); | 236 | pte[1] = (__force u64)cpu_to_be64(pte[1]); |
| 236 | copy_to_user((void __user *)pteg, pte, sizeof(pte)); | 237 | copy_to_user((void __user *)pteg, pte, sizeof(pte)); |
| 237 | ret = H_SUCCESS; | 238 | ret = H_SUCCESS; |
| 238 | 239 | ||
| @@ -266,6 +267,12 @@ static int kvmppc_h_pr_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd) | |||
| 266 | 267 | ||
| 267 | int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd) | 268 | int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd) |
| 268 | { | 269 | { |
| 270 | int rc, idx; | ||
| 271 | |||
| 272 | if (cmd <= MAX_HCALL_OPCODE && | ||
| 273 | !test_bit(cmd/4, vcpu->kvm->arch.enabled_hcalls)) | ||
| 274 | return EMULATE_FAIL; | ||
| 275 | |||
| 269 | switch (cmd) { | 276 | switch (cmd) { |
| 270 | case H_ENTER: | 277 | case H_ENTER: |
| 271 | return kvmppc_h_pr_enter(vcpu); | 278 | return kvmppc_h_pr_enter(vcpu); |
| @@ -294,8 +301,11 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd) | |||
| 294 | break; | 301 | break; |
| 295 | case H_RTAS: | 302 | case H_RTAS: |
| 296 | if (list_empty(&vcpu->kvm->arch.rtas_tokens)) | 303 | if (list_empty(&vcpu->kvm->arch.rtas_tokens)) |
| 297 | return RESUME_HOST; | 304 | break; |
| 298 | if (kvmppc_rtas_hcall(vcpu)) | 305 | idx = srcu_read_lock(&vcpu->kvm->srcu); |
| 306 | rc = kvmppc_rtas_hcall(vcpu); | ||
| 307 | srcu_read_unlock(&vcpu->kvm->srcu, idx); | ||
| 308 | if (rc) | ||
| 299 | break; | 309 | break; |
| 300 | kvmppc_set_gpr(vcpu, 3, 0); | 310 | kvmppc_set_gpr(vcpu, 3, 0); |
| 301 | return EMULATE_DONE; | 311 | return EMULATE_DONE; |
| @@ -303,3 +313,61 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd) | |||
| 303 | 313 | ||
| 304 | return EMULATE_FAIL; | 314 | return EMULATE_FAIL; |
| 305 | } | 315 | } |
| 316 | |||
| 317 | int kvmppc_hcall_impl_pr(unsigned long cmd) | ||
| 318 | { | ||
| 319 | switch (cmd) { | ||
| 320 | case H_ENTER: | ||
| 321 | case H_REMOVE: | ||
| 322 | case H_PROTECT: | ||
| 323 | case H_BULK_REMOVE: | ||
| 324 | case H_PUT_TCE: | ||
| 325 | case H_CEDE: | ||
| 326 | #ifdef CONFIG_KVM_XICS | ||
| 327 | case H_XIRR: | ||
| 328 | case H_CPPR: | ||
| 329 | case H_EOI: | ||
| 330 | case H_IPI: | ||
| 331 | case H_IPOLL: | ||
| 332 | case H_XIRR_X: | ||
| 333 | #endif | ||
| 334 | return 1; | ||
| 335 | } | ||
| 336 | return 0; | ||
| 337 | } | ||
| 338 | |||
| 339 | /* | ||
| 340 | * List of hcall numbers to enable by default. | ||
| 341 | * For compatibility with old userspace, we enable by default | ||
| 342 | * all hcalls that were implemented before the hcall-enabling | ||
| 343 | * facility was added. Note this list should not include H_RTAS. | ||
| 344 | */ | ||
| 345 | static unsigned int default_hcall_list[] = { | ||
| 346 | H_ENTER, | ||
| 347 | H_REMOVE, | ||
| 348 | H_PROTECT, | ||
| 349 | H_BULK_REMOVE, | ||
| 350 | H_PUT_TCE, | ||
| 351 | H_CEDE, | ||
| 352 | #ifdef CONFIG_KVM_XICS | ||
| 353 | H_XIRR, | ||
| 354 | H_CPPR, | ||
| 355 | H_EOI, | ||
| 356 | H_IPI, | ||
| 357 | H_IPOLL, | ||
| 358 | H_XIRR_X, | ||
| 359 | #endif | ||
| 360 | 0 | ||
| 361 | }; | ||
| 362 | |||
| 363 | void kvmppc_pr_init_default_hcalls(struct kvm *kvm) | ||
| 364 | { | ||
| 365 | int i; | ||
| 366 | unsigned int hcall; | ||
| 367 | |||
| 368 | for (i = 0; default_hcall_list[i]; ++i) { | ||
| 369 | hcall = default_hcall_list[i]; | ||
| 370 | WARN_ON(!kvmppc_hcall_impl_pr(hcall)); | ||
| 371 | __set_bit(hcall / 4, kvm->arch.enabled_hcalls); | ||
| 372 | } | ||
| 373 | } | ||
diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c index d1acd32a64c0..eaeb78047fb8 100644 --- a/arch/powerpc/kvm/book3s_xics.c +++ b/arch/powerpc/kvm/book3s_xics.c | |||
| @@ -64,8 +64,12 @@ | |||
| 64 | static void icp_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp, | 64 | static void icp_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp, |
| 65 | u32 new_irq); | 65 | u32 new_irq); |
| 66 | 66 | ||
| 67 | static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level, | 67 | /* |
| 68 | bool report_status) | 68 | * Return value ideally indicates how the interrupt was handled, but no |
| 69 | * callers look at it (given that we don't implement KVM_IRQ_LINE_STATUS), | ||
| 70 | * so just return 0. | ||
| 71 | */ | ||
| 72 | static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level) | ||
| 69 | { | 73 | { |
| 70 | struct ics_irq_state *state; | 74 | struct ics_irq_state *state; |
| 71 | struct kvmppc_ics *ics; | 75 | struct kvmppc_ics *ics; |
| @@ -82,17 +86,14 @@ static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level, | |||
| 82 | if (!state->exists) | 86 | if (!state->exists) |
| 83 | return -EINVAL; | 87 | return -EINVAL; |
| 84 | 88 | ||
| 85 | if (report_status) | ||
| 86 | return state->asserted; | ||
| 87 | |||
| 88 | /* | 89 | /* |
| 89 | * We set state->asserted locklessly. This should be fine as | 90 | * We set state->asserted locklessly. This should be fine as |
| 90 | * we are the only setter, thus concurrent access is undefined | 91 | * we are the only setter, thus concurrent access is undefined |
| 91 | * to begin with. | 92 | * to begin with. |
| 92 | */ | 93 | */ |
| 93 | if (level == KVM_INTERRUPT_SET_LEVEL) | 94 | if (level == 1 || level == KVM_INTERRUPT_SET_LEVEL) |
| 94 | state->asserted = 1; | 95 | state->asserted = 1; |
| 95 | else if (level == KVM_INTERRUPT_UNSET) { | 96 | else if (level == 0 || level == KVM_INTERRUPT_UNSET) { |
| 96 | state->asserted = 0; | 97 | state->asserted = 0; |
| 97 | return 0; | 98 | return 0; |
| 98 | } | 99 | } |
| @@ -100,7 +101,7 @@ static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level, | |||
| 100 | /* Attempt delivery */ | 101 | /* Attempt delivery */ |
| 101 | icp_deliver_irq(xics, NULL, irq); | 102 | icp_deliver_irq(xics, NULL, irq); |
| 102 | 103 | ||
| 103 | return state->asserted; | 104 | return 0; |
| 104 | } | 105 | } |
| 105 | 106 | ||
| 106 | static void ics_check_resend(struct kvmppc_xics *xics, struct kvmppc_ics *ics, | 107 | static void ics_check_resend(struct kvmppc_xics *xics, struct kvmppc_ics *ics, |
| @@ -772,6 +773,8 @@ static noinline int kvmppc_h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr) | |||
| 772 | if (state->asserted) | 773 | if (state->asserted) |
| 773 | icp_deliver_irq(xics, icp, irq); | 774 | icp_deliver_irq(xics, icp, irq); |
| 774 | 775 | ||
| 776 | kvm_notify_acked_irq(vcpu->kvm, 0, irq); | ||
| 777 | |||
| 775 | return H_SUCCESS; | 778 | return H_SUCCESS; |
| 776 | } | 779 | } |
| 777 | 780 | ||
| @@ -789,6 +792,8 @@ static noinline int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall) | |||
| 789 | icp_check_resend(xics, icp); | 792 | icp_check_resend(xics, icp); |
| 790 | if (icp->rm_action & XICS_RM_REJECT) | 793 | if (icp->rm_action & XICS_RM_REJECT) |
| 791 | icp_deliver_irq(xics, icp, icp->rm_reject); | 794 | icp_deliver_irq(xics, icp, icp->rm_reject); |
| 795 | if (icp->rm_action & XICS_RM_NOTIFY_EOI) | ||
| 796 | kvm_notify_acked_irq(vcpu->kvm, 0, icp->rm_eoied_irq); | ||
| 792 | 797 | ||
| 793 | icp->rm_action = 0; | 798 | icp->rm_action = 0; |
| 794 | 799 | ||
| @@ -1170,7 +1175,16 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level, | |||
| 1170 | { | 1175 | { |
| 1171 | struct kvmppc_xics *xics = kvm->arch.xics; | 1176 | struct kvmppc_xics *xics = kvm->arch.xics; |
| 1172 | 1177 | ||
| 1173 | return ics_deliver_irq(xics, irq, level, line_status); | 1178 | return ics_deliver_irq(xics, irq, level); |
| 1179 | } | ||
| 1180 | |||
| 1181 | int kvm_set_msi(struct kvm_kernel_irq_routing_entry *irq_entry, struct kvm *kvm, | ||
| 1182 | int irq_source_id, int level, bool line_status) | ||
| 1183 | { | ||
| 1184 | if (!level) | ||
| 1185 | return -1; | ||
| 1186 | return kvm_set_irq(kvm, irq_source_id, irq_entry->gsi, | ||
| 1187 | level, line_status); | ||
| 1174 | } | 1188 | } |
| 1175 | 1189 | ||
| 1176 | static int xics_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) | 1190 | static int xics_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) |
| @@ -1301,3 +1315,26 @@ void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu) | |||
| 1301 | vcpu->arch.icp = NULL; | 1315 | vcpu->arch.icp = NULL; |
| 1302 | vcpu->arch.irq_type = KVMPPC_IRQ_DEFAULT; | 1316 | vcpu->arch.irq_type = KVMPPC_IRQ_DEFAULT; |
| 1303 | } | 1317 | } |
| 1318 | |||
| 1319 | static int xics_set_irq(struct kvm_kernel_irq_routing_entry *e, | ||
| 1320 | struct kvm *kvm, int irq_source_id, int level, | ||
| 1321 | bool line_status) | ||
| 1322 | { | ||
| 1323 | return kvm_set_irq(kvm, irq_source_id, e->gsi, level, line_status); | ||
| 1324 | } | ||
| 1325 | |||
| 1326 | int kvm_irq_map_gsi(struct kvm *kvm, | ||
| 1327 | struct kvm_kernel_irq_routing_entry *entries, int gsi) | ||
| 1328 | { | ||
| 1329 | entries->gsi = gsi; | ||
| 1330 | entries->type = KVM_IRQ_ROUTING_IRQCHIP; | ||
| 1331 | entries->set = xics_set_irq; | ||
| 1332 | entries->irqchip.irqchip = 0; | ||
| 1333 | entries->irqchip.pin = gsi; | ||
| 1334 | return 1; | ||
| 1335 | } | ||
| 1336 | |||
| 1337 | int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin) | ||
| 1338 | { | ||
| 1339 | return pin; | ||
| 1340 | } | ||
diff --git a/arch/powerpc/kvm/book3s_xics.h b/arch/powerpc/kvm/book3s_xics.h index dd9326c5c19b..e8aaa7a3f209 100644 --- a/arch/powerpc/kvm/book3s_xics.h +++ b/arch/powerpc/kvm/book3s_xics.h | |||
| @@ -71,9 +71,11 @@ struct kvmppc_icp { | |||
| 71 | #define XICS_RM_KICK_VCPU 0x1 | 71 | #define XICS_RM_KICK_VCPU 0x1 |
| 72 | #define XICS_RM_CHECK_RESEND 0x2 | 72 | #define XICS_RM_CHECK_RESEND 0x2 |
| 73 | #define XICS_RM_REJECT 0x4 | 73 | #define XICS_RM_REJECT 0x4 |
| 74 | #define XICS_RM_NOTIFY_EOI 0x8 | ||
| 74 | u32 rm_action; | 75 | u32 rm_action; |
| 75 | struct kvm_vcpu *rm_kick_target; | 76 | struct kvm_vcpu *rm_kick_target; |
| 76 | u32 rm_reject; | 77 | u32 rm_reject; |
| 78 | u32 rm_eoied_irq; | ||
| 77 | 79 | ||
| 78 | /* Debug stuff for real mode */ | 80 | /* Debug stuff for real mode */ |
| 79 | union kvmppc_icp_state rm_dbgstate; | 81 | union kvmppc_icp_state rm_dbgstate; |
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index ab62109fdfa3..b4c89fa6f109 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c | |||
| @@ -51,7 +51,6 @@ unsigned long kvmppc_booke_handlers; | |||
| 51 | 51 | ||
| 52 | struct kvm_stats_debugfs_item debugfs_entries[] = { | 52 | struct kvm_stats_debugfs_item debugfs_entries[] = { |
| 53 | { "mmio", VCPU_STAT(mmio_exits) }, | 53 | { "mmio", VCPU_STAT(mmio_exits) }, |
| 54 | { "dcr", VCPU_STAT(dcr_exits) }, | ||
| 55 | { "sig", VCPU_STAT(signal_exits) }, | 54 | { "sig", VCPU_STAT(signal_exits) }, |
| 56 | { "itlb_r", VCPU_STAT(itlb_real_miss_exits) }, | 55 | { "itlb_r", VCPU_STAT(itlb_real_miss_exits) }, |
| 57 | { "itlb_v", VCPU_STAT(itlb_virt_miss_exits) }, | 56 | { "itlb_v", VCPU_STAT(itlb_virt_miss_exits) }, |
| @@ -185,24 +184,28 @@ static void kvmppc_booke_queue_irqprio(struct kvm_vcpu *vcpu, | |||
| 185 | set_bit(priority, &vcpu->arch.pending_exceptions); | 184 | set_bit(priority, &vcpu->arch.pending_exceptions); |
| 186 | } | 185 | } |
| 187 | 186 | ||
| 188 | static void kvmppc_core_queue_dtlb_miss(struct kvm_vcpu *vcpu, | 187 | void kvmppc_core_queue_dtlb_miss(struct kvm_vcpu *vcpu, |
| 189 | ulong dear_flags, ulong esr_flags) | 188 | ulong dear_flags, ulong esr_flags) |
| 190 | { | 189 | { |
| 191 | vcpu->arch.queued_dear = dear_flags; | 190 | vcpu->arch.queued_dear = dear_flags; |
| 192 | vcpu->arch.queued_esr = esr_flags; | 191 | vcpu->arch.queued_esr = esr_flags; |
| 193 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DTLB_MISS); | 192 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DTLB_MISS); |
| 194 | } | 193 | } |
| 195 | 194 | ||
| 196 | static void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu, | 195 | void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu, |
| 197 | ulong dear_flags, ulong esr_flags) | 196 | ulong dear_flags, ulong esr_flags) |
| 198 | { | 197 | { |
| 199 | vcpu->arch.queued_dear = dear_flags; | 198 | vcpu->arch.queued_dear = dear_flags; |
| 200 | vcpu->arch.queued_esr = esr_flags; | 199 | vcpu->arch.queued_esr = esr_flags; |
| 201 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DATA_STORAGE); | 200 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DATA_STORAGE); |
| 202 | } | 201 | } |
| 203 | 202 | ||
| 204 | static void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu, | 203 | void kvmppc_core_queue_itlb_miss(struct kvm_vcpu *vcpu) |
| 205 | ulong esr_flags) | 204 | { |
| 205 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_ITLB_MISS); | ||
| 206 | } | ||
| 207 | |||
| 208 | void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu, ulong esr_flags) | ||
| 206 | { | 209 | { |
| 207 | vcpu->arch.queued_esr = esr_flags; | 210 | vcpu->arch.queued_esr = esr_flags; |
| 208 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_INST_STORAGE); | 211 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_INST_STORAGE); |
| @@ -266,13 +269,8 @@ static void kvmppc_core_dequeue_watchdog(struct kvm_vcpu *vcpu) | |||
| 266 | 269 | ||
| 267 | static void set_guest_srr(struct kvm_vcpu *vcpu, unsigned long srr0, u32 srr1) | 270 | static void set_guest_srr(struct kvm_vcpu *vcpu, unsigned long srr0, u32 srr1) |
| 268 | { | 271 | { |
| 269 | #ifdef CONFIG_KVM_BOOKE_HV | 272 | kvmppc_set_srr0(vcpu, srr0); |
| 270 | mtspr(SPRN_GSRR0, srr0); | 273 | kvmppc_set_srr1(vcpu, srr1); |
| 271 | mtspr(SPRN_GSRR1, srr1); | ||
| 272 | #else | ||
| 273 | vcpu->arch.shared->srr0 = srr0; | ||
| 274 | vcpu->arch.shared->srr1 = srr1; | ||
| 275 | #endif | ||
| 276 | } | 274 | } |
| 277 | 275 | ||
| 278 | static void set_guest_csrr(struct kvm_vcpu *vcpu, unsigned long srr0, u32 srr1) | 276 | static void set_guest_csrr(struct kvm_vcpu *vcpu, unsigned long srr0, u32 srr1) |
| @@ -297,51 +295,6 @@ static void set_guest_mcsrr(struct kvm_vcpu *vcpu, unsigned long srr0, u32 srr1) | |||
| 297 | vcpu->arch.mcsrr1 = srr1; | 295 | vcpu->arch.mcsrr1 = srr1; |
| 298 | } | 296 | } |
| 299 | 297 | ||
| 300 | static unsigned long get_guest_dear(struct kvm_vcpu *vcpu) | ||
| 301 | { | ||
| 302 | #ifdef CONFIG_KVM_BOOKE_HV | ||
| 303 | return mfspr(SPRN_GDEAR); | ||
| 304 | #else | ||
| 305 | return vcpu->arch.shared->dar; | ||
| 306 | #endif | ||
| 307 | } | ||
| 308 | |||
| 309 | static void set_guest_dear(struct kvm_vcpu *vcpu, unsigned long dear) | ||
| 310 | { | ||
| 311 | #ifdef CONFIG_KVM_BOOKE_HV | ||
| 312 | mtspr(SPRN_GDEAR, dear); | ||
| 313 | #else | ||
| 314 | vcpu->arch.shared->dar = dear; | ||
| 315 | #endif | ||
| 316 | } | ||
| 317 | |||
| 318 | static unsigned long get_guest_esr(struct kvm_vcpu *vcpu) | ||
| 319 | { | ||
| 320 | #ifdef CONFIG_KVM_BOOKE_HV | ||
| 321 | return mfspr(SPRN_GESR); | ||
| 322 | #else | ||
| 323 | return vcpu->arch.shared->esr; | ||
| 324 | #endif | ||
| 325 | } | ||
| 326 | |||
| 327 | static void set_guest_esr(struct kvm_vcpu *vcpu, u32 esr) | ||
| 328 | { | ||
| 329 | #ifdef CONFIG_KVM_BOOKE_HV | ||
| 330 | mtspr(SPRN_GESR, esr); | ||
| 331 | #else | ||
| 332 | vcpu->arch.shared->esr = esr; | ||
| 333 | #endif | ||
| 334 | } | ||
| 335 | |||
| 336 | static unsigned long get_guest_epr(struct kvm_vcpu *vcpu) | ||
| 337 | { | ||
| 338 | #ifdef CONFIG_KVM_BOOKE_HV | ||
| 339 | return mfspr(SPRN_GEPR); | ||
| 340 | #else | ||
| 341 | return vcpu->arch.epr; | ||
| 342 | #endif | ||
| 343 | } | ||
| 344 | |||
| 345 | /* Deliver the interrupt of the corresponding priority, if possible. */ | 298 | /* Deliver the interrupt of the corresponding priority, if possible. */ |
| 346 | static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, | 299 | static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, |
| 347 | unsigned int priority) | 300 | unsigned int priority) |
| @@ -450,9 +403,9 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, | |||
| 450 | 403 | ||
| 451 | vcpu->arch.pc = vcpu->arch.ivpr | vcpu->arch.ivor[priority]; | 404 | vcpu->arch.pc = vcpu->arch.ivpr | vcpu->arch.ivor[priority]; |
| 452 | if (update_esr == true) | 405 | if (update_esr == true) |
| 453 | set_guest_esr(vcpu, vcpu->arch.queued_esr); | 406 | kvmppc_set_esr(vcpu, vcpu->arch.queued_esr); |
| 454 | if (update_dear == true) | 407 | if (update_dear == true) |
| 455 | set_guest_dear(vcpu, vcpu->arch.queued_dear); | 408 | kvmppc_set_dar(vcpu, vcpu->arch.queued_dear); |
| 456 | if (update_epr == true) { | 409 | if (update_epr == true) { |
| 457 | if (vcpu->arch.epr_flags & KVMPPC_EPR_USER) | 410 | if (vcpu->arch.epr_flags & KVMPPC_EPR_USER) |
| 458 | kvm_make_request(KVM_REQ_EPR_EXIT, vcpu); | 411 | kvm_make_request(KVM_REQ_EPR_EXIT, vcpu); |
| @@ -752,9 +705,8 @@ static int emulation_exit(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
| 752 | * they were actually modified by emulation. */ | 705 | * they were actually modified by emulation. */ |
| 753 | return RESUME_GUEST_NV; | 706 | return RESUME_GUEST_NV; |
| 754 | 707 | ||
| 755 | case EMULATE_DO_DCR: | 708 | case EMULATE_AGAIN: |
| 756 | run->exit_reason = KVM_EXIT_DCR; | 709 | return RESUME_GUEST; |
| 757 | return RESUME_HOST; | ||
| 758 | 710 | ||
| 759 | case EMULATE_FAIL: | 711 | case EMULATE_FAIL: |
| 760 | printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n", | 712 | printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n", |
| @@ -866,6 +818,28 @@ static void kvmppc_restart_interrupt(struct kvm_vcpu *vcpu, | |||
| 866 | } | 818 | } |
| 867 | } | 819 | } |
| 868 | 820 | ||
| 821 | static int kvmppc_resume_inst_load(struct kvm_run *run, struct kvm_vcpu *vcpu, | ||
| 822 | enum emulation_result emulated, u32 last_inst) | ||
| 823 | { | ||
| 824 | switch (emulated) { | ||
| 825 | case EMULATE_AGAIN: | ||
| 826 | return RESUME_GUEST; | ||
| 827 | |||
| 828 | case EMULATE_FAIL: | ||
| 829 | pr_debug("%s: load instruction from guest address %lx failed\n", | ||
| 830 | __func__, vcpu->arch.pc); | ||
| 831 | /* For debugging, encode the failing instruction and | ||
| 832 | * report it to userspace. */ | ||
| 833 | run->hw.hardware_exit_reason = ~0ULL << 32; | ||
| 834 | run->hw.hardware_exit_reason |= last_inst; | ||
| 835 | kvmppc_core_queue_program(vcpu, ESR_PIL); | ||
| 836 | return RESUME_HOST; | ||
| 837 | |||
| 838 | default: | ||
| 839 | BUG(); | ||
| 840 | } | ||
| 841 | } | ||
| 842 | |||
| 869 | /** | 843 | /** |
| 870 | * kvmppc_handle_exit | 844 | * kvmppc_handle_exit |
| 871 | * | 845 | * |
| @@ -877,6 +851,8 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
| 877 | int r = RESUME_HOST; | 851 | int r = RESUME_HOST; |
| 878 | int s; | 852 | int s; |
| 879 | int idx; | 853 | int idx; |
| 854 | u32 last_inst = KVM_INST_FETCH_FAILED; | ||
| 855 | enum emulation_result emulated = EMULATE_DONE; | ||
| 880 | 856 | ||
| 881 | /* update before a new last_exit_type is rewritten */ | 857 | /* update before a new last_exit_type is rewritten */ |
| 882 | kvmppc_update_timing_stats(vcpu); | 858 | kvmppc_update_timing_stats(vcpu); |
| @@ -884,6 +860,20 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
| 884 | /* restart interrupts if they were meant for the host */ | 860 | /* restart interrupts if they were meant for the host */ |
| 885 | kvmppc_restart_interrupt(vcpu, exit_nr); | 861 | kvmppc_restart_interrupt(vcpu, exit_nr); |
| 886 | 862 | ||
| 863 | /* | ||
| 864 | * get last instruction before beeing preempted | ||
| 865 | * TODO: for e6500 check also BOOKE_INTERRUPT_LRAT_ERROR & ESR_DATA | ||
| 866 | */ | ||
| 867 | switch (exit_nr) { | ||
| 868 | case BOOKE_INTERRUPT_DATA_STORAGE: | ||
| 869 | case BOOKE_INTERRUPT_DTLB_MISS: | ||
| 870 | case BOOKE_INTERRUPT_HV_PRIV: | ||
| 871 | emulated = kvmppc_get_last_inst(vcpu, false, &last_inst); | ||
| 872 | break; | ||
| 873 | default: | ||
| 874 | break; | ||
| 875 | } | ||
| 876 | |||
| 887 | local_irq_enable(); | 877 | local_irq_enable(); |
| 888 | 878 | ||
| 889 | trace_kvm_exit(exit_nr, vcpu); | 879 | trace_kvm_exit(exit_nr, vcpu); |
| @@ -892,6 +882,11 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
| 892 | run->exit_reason = KVM_EXIT_UNKNOWN; | 882 | run->exit_reason = KVM_EXIT_UNKNOWN; |
| 893 | run->ready_for_interrupt_injection = 1; | 883 | run->ready_for_interrupt_injection = 1; |
| 894 | 884 | ||
| 885 | if (emulated != EMULATE_DONE) { | ||
| 886 | r = kvmppc_resume_inst_load(run, vcpu, emulated, last_inst); | ||
| 887 | goto out; | ||
| 888 | } | ||
| 889 | |||
| 895 | switch (exit_nr) { | 890 | switch (exit_nr) { |
| 896 | case BOOKE_INTERRUPT_MACHINE_CHECK: | 891 | case BOOKE_INTERRUPT_MACHINE_CHECK: |
| 897 | printk("MACHINE CHECK: %lx\n", mfspr(SPRN_MCSR)); | 892 | printk("MACHINE CHECK: %lx\n", mfspr(SPRN_MCSR)); |
| @@ -1181,6 +1176,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
| 1181 | BUG(); | 1176 | BUG(); |
| 1182 | } | 1177 | } |
| 1183 | 1178 | ||
| 1179 | out: | ||
| 1184 | /* | 1180 | /* |
| 1185 | * To avoid clobbering exit_reason, only check for signals if we | 1181 | * To avoid clobbering exit_reason, only check for signals if we |
| 1186 | * aren't already exiting to userspace for some other reason. | 1182 | * aren't already exiting to userspace for some other reason. |
| @@ -1265,17 +1261,17 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
| 1265 | regs->lr = vcpu->arch.lr; | 1261 | regs->lr = vcpu->arch.lr; |
| 1266 | regs->xer = kvmppc_get_xer(vcpu); | 1262 | regs->xer = kvmppc_get_xer(vcpu); |
| 1267 | regs->msr = vcpu->arch.shared->msr; | 1263 | regs->msr = vcpu->arch.shared->msr; |
| 1268 | regs->srr0 = vcpu->arch.shared->srr0; | 1264 | regs->srr0 = kvmppc_get_srr0(vcpu); |
| 1269 | regs->srr1 = vcpu->arch.shared->srr1; | 1265 | regs->srr1 = kvmppc_get_srr1(vcpu); |
| 1270 | regs->pid = vcpu->arch.pid; | 1266 | regs->pid = vcpu->arch.pid; |
| 1271 | regs->sprg0 = vcpu->arch.shared->sprg0; | 1267 | regs->sprg0 = kvmppc_get_sprg0(vcpu); |
| 1272 | regs->sprg1 = vcpu->arch.shared->sprg1; | 1268 | regs->sprg1 = kvmppc_get_sprg1(vcpu); |
| 1273 | regs->sprg2 = vcpu->arch.shared->sprg2; | 1269 | regs->sprg2 = kvmppc_get_sprg2(vcpu); |
| 1274 | regs->sprg3 = vcpu->arch.shared->sprg3; | 1270 | regs->sprg3 = kvmppc_get_sprg3(vcpu); |
| 1275 | regs->sprg4 = vcpu->arch.shared->sprg4; | 1271 | regs->sprg4 = kvmppc_get_sprg4(vcpu); |
| 1276 | regs->sprg5 = vcpu->arch.shared->sprg5; | 1272 | regs->sprg5 = kvmppc_get_sprg5(vcpu); |
| 1277 | regs->sprg6 = vcpu->arch.shared->sprg6; | 1273 | regs->sprg6 = kvmppc_get_sprg6(vcpu); |
| 1278 | regs->sprg7 = vcpu->arch.shared->sprg7; | 1274 | regs->sprg7 = kvmppc_get_sprg7(vcpu); |
| 1279 | 1275 | ||
| 1280 | for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) | 1276 | for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) |
| 1281 | regs->gpr[i] = kvmppc_get_gpr(vcpu, i); | 1277 | regs->gpr[i] = kvmppc_get_gpr(vcpu, i); |
| @@ -1293,17 +1289,17 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
| 1293 | vcpu->arch.lr = regs->lr; | 1289 | vcpu->arch.lr = regs->lr; |
| 1294 | kvmppc_set_xer(vcpu, regs->xer); | 1290 | kvmppc_set_xer(vcpu, regs->xer); |
| 1295 | kvmppc_set_msr(vcpu, regs->msr); | 1291 | kvmppc_set_msr(vcpu, regs->msr); |
| 1296 | vcpu->arch.shared->srr0 = regs->srr0; | 1292 | kvmppc_set_srr0(vcpu, regs->srr0); |
| 1297 | vcpu->arch.shared->srr1 = regs->srr1; | 1293 | kvmppc_set_srr1(vcpu, regs->srr1); |
| 1298 | kvmppc_set_pid(vcpu, regs->pid); | 1294 | kvmppc_set_pid(vcpu, regs->pid); |
| 1299 | vcpu->arch.shared->sprg0 = regs->sprg0; | 1295 | kvmppc_set_sprg0(vcpu, regs->sprg0); |
| 1300 | vcpu->arch.shared->sprg1 = regs->sprg1; | 1296 | kvmppc_set_sprg1(vcpu, regs->sprg1); |
| 1301 | vcpu->arch.shared->sprg2 = regs->sprg2; | 1297 | kvmppc_set_sprg2(vcpu, regs->sprg2); |
| 1302 | vcpu->arch.shared->sprg3 = regs->sprg3; | 1298 | kvmppc_set_sprg3(vcpu, regs->sprg3); |
| 1303 | vcpu->arch.shared->sprg4 = regs->sprg4; | 1299 | kvmppc_set_sprg4(vcpu, regs->sprg4); |
| 1304 | vcpu->arch.shared->sprg5 = regs->sprg5; | 1300 | kvmppc_set_sprg5(vcpu, regs->sprg5); |
| 1305 | vcpu->arch.shared->sprg6 = regs->sprg6; | 1301 | kvmppc_set_sprg6(vcpu, regs->sprg6); |
| 1306 | vcpu->arch.shared->sprg7 = regs->sprg7; | 1302 | kvmppc_set_sprg7(vcpu, regs->sprg7); |
| 1307 | 1303 | ||
| 1308 | for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) | 1304 | for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) |
| 1309 | kvmppc_set_gpr(vcpu, i, regs->gpr[i]); | 1305 | kvmppc_set_gpr(vcpu, i, regs->gpr[i]); |
| @@ -1321,8 +1317,8 @@ static void get_sregs_base(struct kvm_vcpu *vcpu, | |||
| 1321 | sregs->u.e.csrr0 = vcpu->arch.csrr0; | 1317 | sregs->u.e.csrr0 = vcpu->arch.csrr0; |
| 1322 | sregs->u.e.csrr1 = vcpu->arch.csrr1; | 1318 | sregs->u.e.csrr1 = vcpu->arch.csrr1; |
| 1323 | sregs->u.e.mcsr = vcpu->arch.mcsr; | 1319 | sregs->u.e.mcsr = vcpu->arch.mcsr; |
| 1324 | sregs->u.e.esr = get_guest_esr(vcpu); | 1320 | sregs->u.e.esr = kvmppc_get_esr(vcpu); |
| 1325 | sregs->u.e.dear = get_guest_dear(vcpu); | 1321 | sregs->u.e.dear = kvmppc_get_dar(vcpu); |
| 1326 | sregs->u.e.tsr = vcpu->arch.tsr; | 1322 | sregs->u.e.tsr = vcpu->arch.tsr; |
| 1327 | sregs->u.e.tcr = vcpu->arch.tcr; | 1323 | sregs->u.e.tcr = vcpu->arch.tcr; |
| 1328 | sregs->u.e.dec = kvmppc_get_dec(vcpu, tb); | 1324 | sregs->u.e.dec = kvmppc_get_dec(vcpu, tb); |
| @@ -1339,8 +1335,8 @@ static int set_sregs_base(struct kvm_vcpu *vcpu, | |||
| 1339 | vcpu->arch.csrr0 = sregs->u.e.csrr0; | 1335 | vcpu->arch.csrr0 = sregs->u.e.csrr0; |
| 1340 | vcpu->arch.csrr1 = sregs->u.e.csrr1; | 1336 | vcpu->arch.csrr1 = sregs->u.e.csrr1; |
| 1341 | vcpu->arch.mcsr = sregs->u.e.mcsr; | 1337 | vcpu->arch.mcsr = sregs->u.e.mcsr; |
| 1342 | set_guest_esr(vcpu, sregs->u.e.esr); | 1338 | kvmppc_set_esr(vcpu, sregs->u.e.esr); |
| 1343 | set_guest_dear(vcpu, sregs->u.e.dear); | 1339 | kvmppc_set_dar(vcpu, sregs->u.e.dear); |
| 1344 | vcpu->arch.vrsave = sregs->u.e.vrsave; | 1340 | vcpu->arch.vrsave = sregs->u.e.vrsave; |
| 1345 | kvmppc_set_tcr(vcpu, sregs->u.e.tcr); | 1341 | kvmppc_set_tcr(vcpu, sregs->u.e.tcr); |
| 1346 | 1342 | ||
| @@ -1493,7 +1489,7 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) | |||
| 1493 | val = get_reg_val(reg->id, vcpu->arch.dbg_reg.dac2); | 1489 | val = get_reg_val(reg->id, vcpu->arch.dbg_reg.dac2); |
| 1494 | break; | 1490 | break; |
| 1495 | case KVM_REG_PPC_EPR: { | 1491 | case KVM_REG_PPC_EPR: { |
| 1496 | u32 epr = get_guest_epr(vcpu); | 1492 | u32 epr = kvmppc_get_epr(vcpu); |
| 1497 | val = get_reg_val(reg->id, epr); | 1493 | val = get_reg_val(reg->id, epr); |
| 1498 | break; | 1494 | break; |
| 1499 | } | 1495 | } |
| @@ -1788,6 +1784,57 @@ void kvm_guest_protect_msr(struct kvm_vcpu *vcpu, ulong prot_bitmap, bool set) | |||
| 1788 | #endif | 1784 | #endif |
| 1789 | } | 1785 | } |
| 1790 | 1786 | ||
| 1787 | int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, enum xlate_instdata xlid, | ||
| 1788 | enum xlate_readwrite xlrw, struct kvmppc_pte *pte) | ||
| 1789 | { | ||
| 1790 | int gtlb_index; | ||
| 1791 | gpa_t gpaddr; | ||
| 1792 | |||
| 1793 | #ifdef CONFIG_KVM_E500V2 | ||
| 1794 | if (!(vcpu->arch.shared->msr & MSR_PR) && | ||
| 1795 | (eaddr & PAGE_MASK) == vcpu->arch.magic_page_ea) { | ||
| 1796 | pte->eaddr = eaddr; | ||
| 1797 | pte->raddr = (vcpu->arch.magic_page_pa & PAGE_MASK) | | ||
| 1798 | (eaddr & ~PAGE_MASK); | ||
| 1799 | pte->vpage = eaddr >> PAGE_SHIFT; | ||
| 1800 | pte->may_read = true; | ||
| 1801 | pte->may_write = true; | ||
| 1802 | pte->may_execute = true; | ||
| 1803 | |||
| 1804 | return 0; | ||
| 1805 | } | ||
| 1806 | #endif | ||
| 1807 | |||
| 1808 | /* Check the guest TLB. */ | ||
| 1809 | switch (xlid) { | ||
| 1810 | case XLATE_INST: | ||
| 1811 | gtlb_index = kvmppc_mmu_itlb_index(vcpu, eaddr); | ||
| 1812 | break; | ||
| 1813 | case XLATE_DATA: | ||
| 1814 | gtlb_index = kvmppc_mmu_dtlb_index(vcpu, eaddr); | ||
| 1815 | break; | ||
| 1816 | default: | ||
| 1817 | BUG(); | ||
| 1818 | } | ||
| 1819 | |||
| 1820 | /* Do we have a TLB entry at all? */ | ||
| 1821 | if (gtlb_index < 0) | ||
| 1822 | return -ENOENT; | ||
| 1823 | |||
| 1824 | gpaddr = kvmppc_mmu_xlate(vcpu, gtlb_index, eaddr); | ||
| 1825 | |||
| 1826 | pte->eaddr = eaddr; | ||
| 1827 | pte->raddr = (gpaddr & PAGE_MASK) | (eaddr & ~PAGE_MASK); | ||
| 1828 | pte->vpage = eaddr >> PAGE_SHIFT; | ||
| 1829 | |||
| 1830 | /* XXX read permissions from the guest TLB */ | ||
| 1831 | pte->may_read = true; | ||
| 1832 | pte->may_write = true; | ||
| 1833 | pte->may_execute = true; | ||
| 1834 | |||
| 1835 | return 0; | ||
| 1836 | } | ||
| 1837 | |||
| 1791 | int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, | 1838 | int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, |
| 1792 | struct kvm_guest_debug *dbg) | 1839 | struct kvm_guest_debug *dbg) |
| 1793 | { | 1840 | { |
diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h index b632cd35919b..f753543c56fa 100644 --- a/arch/powerpc/kvm/booke.h +++ b/arch/powerpc/kvm/booke.h | |||
| @@ -99,13 +99,6 @@ enum int_class { | |||
| 99 | 99 | ||
| 100 | void kvmppc_set_pending_interrupt(struct kvm_vcpu *vcpu, enum int_class type); | 100 | void kvmppc_set_pending_interrupt(struct kvm_vcpu *vcpu, enum int_class type); |
| 101 | 101 | ||
| 102 | extern void kvmppc_mmu_destroy_44x(struct kvm_vcpu *vcpu); | ||
| 103 | extern int kvmppc_core_emulate_op_44x(struct kvm_run *run, struct kvm_vcpu *vcpu, | ||
| 104 | unsigned int inst, int *advance); | ||
| 105 | extern int kvmppc_core_emulate_mtspr_44x(struct kvm_vcpu *vcpu, int sprn, | ||
| 106 | ulong spr_val); | ||
| 107 | extern int kvmppc_core_emulate_mfspr_44x(struct kvm_vcpu *vcpu, int sprn, | ||
| 108 | ulong *spr_val); | ||
| 109 | extern void kvmppc_mmu_destroy_e500(struct kvm_vcpu *vcpu); | 102 | extern void kvmppc_mmu_destroy_e500(struct kvm_vcpu *vcpu); |
| 110 | extern int kvmppc_core_emulate_op_e500(struct kvm_run *run, | 103 | extern int kvmppc_core_emulate_op_e500(struct kvm_run *run, |
| 111 | struct kvm_vcpu *vcpu, | 104 | struct kvm_vcpu *vcpu, |
diff --git a/arch/powerpc/kvm/booke_emulate.c b/arch/powerpc/kvm/booke_emulate.c index 27a4b2877c10..28c158881d23 100644 --- a/arch/powerpc/kvm/booke_emulate.c +++ b/arch/powerpc/kvm/booke_emulate.c | |||
| @@ -165,16 +165,16 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) | |||
| 165 | * guest (PR-mode only). | 165 | * guest (PR-mode only). |
| 166 | */ | 166 | */ |
| 167 | case SPRN_SPRG4: | 167 | case SPRN_SPRG4: |
| 168 | vcpu->arch.shared->sprg4 = spr_val; | 168 | kvmppc_set_sprg4(vcpu, spr_val); |
| 169 | break; | 169 | break; |
| 170 | case SPRN_SPRG5: | 170 | case SPRN_SPRG5: |
| 171 | vcpu->arch.shared->sprg5 = spr_val; | 171 | kvmppc_set_sprg5(vcpu, spr_val); |
| 172 | break; | 172 | break; |
| 173 | case SPRN_SPRG6: | 173 | case SPRN_SPRG6: |
| 174 | vcpu->arch.shared->sprg6 = spr_val; | 174 | kvmppc_set_sprg6(vcpu, spr_val); |
| 175 | break; | 175 | break; |
| 176 | case SPRN_SPRG7: | 176 | case SPRN_SPRG7: |
| 177 | vcpu->arch.shared->sprg7 = spr_val; | 177 | kvmppc_set_sprg7(vcpu, spr_val); |
| 178 | break; | 178 | break; |
| 179 | 179 | ||
| 180 | case SPRN_IVPR: | 180 | case SPRN_IVPR: |
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S index 2c6deb5ef2fe..84c308a9a371 100644 --- a/arch/powerpc/kvm/booke_interrupts.S +++ b/arch/powerpc/kvm/booke_interrupts.S | |||
| @@ -21,7 +21,6 @@ | |||
| 21 | #include <asm/ppc_asm.h> | 21 | #include <asm/ppc_asm.h> |
| 22 | #include <asm/kvm_asm.h> | 22 | #include <asm/kvm_asm.h> |
| 23 | #include <asm/reg.h> | 23 | #include <asm/reg.h> |
| 24 | #include <asm/mmu-44x.h> | ||
| 25 | #include <asm/page.h> | 24 | #include <asm/page.h> |
| 26 | #include <asm/asm-offsets.h> | 25 | #include <asm/asm-offsets.h> |
| 27 | 26 | ||
| @@ -424,10 +423,6 @@ lightweight_exit: | |||
| 424 | mtspr SPRN_PID1, r3 | 423 | mtspr SPRN_PID1, r3 |
| 425 | #endif | 424 | #endif |
| 426 | 425 | ||
| 427 | #ifdef CONFIG_44x | ||
| 428 | iccci 0, 0 /* XXX hack */ | ||
| 429 | #endif | ||
| 430 | |||
| 431 | /* Load some guest volatiles. */ | 426 | /* Load some guest volatiles. */ |
| 432 | lwz r0, VCPU_GPR(R0)(r4) | 427 | lwz r0, VCPU_GPR(R0)(r4) |
| 433 | lwz r2, VCPU_GPR(R2)(r4) | 428 | lwz r2, VCPU_GPR(R2)(r4) |
diff --git a/arch/powerpc/kvm/bookehv_interrupts.S b/arch/powerpc/kvm/bookehv_interrupts.S index a1712b818a5f..e9fa56a911fd 100644 --- a/arch/powerpc/kvm/bookehv_interrupts.S +++ b/arch/powerpc/kvm/bookehv_interrupts.S | |||
| @@ -24,12 +24,10 @@ | |||
| 24 | #include <asm/ppc_asm.h> | 24 | #include <asm/ppc_asm.h> |
| 25 | #include <asm/kvm_asm.h> | 25 | #include <asm/kvm_asm.h> |
| 26 | #include <asm/reg.h> | 26 | #include <asm/reg.h> |
| 27 | #include <asm/mmu-44x.h> | ||
| 28 | #include <asm/page.h> | 27 | #include <asm/page.h> |
| 29 | #include <asm/asm-compat.h> | 28 | #include <asm/asm-compat.h> |
| 30 | #include <asm/asm-offsets.h> | 29 | #include <asm/asm-offsets.h> |
| 31 | #include <asm/bitsperlong.h> | 30 | #include <asm/bitsperlong.h> |
| 32 | #include <asm/thread_info.h> | ||
| 33 | 31 | ||
| 34 | #ifdef CONFIG_64BIT | 32 | #ifdef CONFIG_64BIT |
| 35 | #include <asm/exception-64e.h> | 33 | #include <asm/exception-64e.h> |
| @@ -122,38 +120,14 @@ | |||
| 122 | 1: | 120 | 1: |
| 123 | 121 | ||
| 124 | .if \flags & NEED_EMU | 122 | .if \flags & NEED_EMU |
| 125 | /* | ||
| 126 | * This assumes you have external PID support. | ||
| 127 | * To support a bookehv CPU without external PID, you'll | ||
| 128 | * need to look up the TLB entry and create a temporary mapping. | ||
| 129 | * | ||
| 130 | * FIXME: we don't currently handle if the lwepx faults. PR-mode | ||
| 131 | * booke doesn't handle it either. Since Linux doesn't use | ||
| 132 | * broadcast tlbivax anymore, the only way this should happen is | ||
| 133 | * if the guest maps its memory execute-but-not-read, or if we | ||
| 134 | * somehow take a TLB miss in the middle of this entry code and | ||
| 135 | * evict the relevant entry. On e500mc, all kernel lowmem is | ||
| 136 | * bolted into TLB1 large page mappings, and we don't use | ||
| 137 | * broadcast invalidates, so we should not take a TLB miss here. | ||
| 138 | * | ||
| 139 | * Later we'll need to deal with faults here. Disallowing guest | ||
| 140 | * mappings that are execute-but-not-read could be an option on | ||
| 141 | * e500mc, but not on chips with an LRAT if it is used. | ||
| 142 | */ | ||
| 143 | |||
| 144 | mfspr r3, SPRN_EPLC /* will already have correct ELPID and EGS */ | ||
| 145 | PPC_STL r15, VCPU_GPR(R15)(r4) | 123 | PPC_STL r15, VCPU_GPR(R15)(r4) |
| 146 | PPC_STL r16, VCPU_GPR(R16)(r4) | 124 | PPC_STL r16, VCPU_GPR(R16)(r4) |
| 147 | PPC_STL r17, VCPU_GPR(R17)(r4) | 125 | PPC_STL r17, VCPU_GPR(R17)(r4) |
| 148 | PPC_STL r18, VCPU_GPR(R18)(r4) | 126 | PPC_STL r18, VCPU_GPR(R18)(r4) |
| 149 | PPC_STL r19, VCPU_GPR(R19)(r4) | 127 | PPC_STL r19, VCPU_GPR(R19)(r4) |
| 150 | mr r8, r3 | ||
| 151 | PPC_STL r20, VCPU_GPR(R20)(r4) | 128 | PPC_STL r20, VCPU_GPR(R20)(r4) |
| 152 | rlwimi r8, r6, EPC_EAS_SHIFT - MSR_IR_LG, EPC_EAS | ||
| 153 | PPC_STL r21, VCPU_GPR(R21)(r4) | 129 | PPC_STL r21, VCPU_GPR(R21)(r4) |
| 154 | rlwimi r8, r6, EPC_EPR_SHIFT - MSR_PR_LG, EPC_EPR | ||
| 155 | PPC_STL r22, VCPU_GPR(R22)(r4) | 130 | PPC_STL r22, VCPU_GPR(R22)(r4) |
| 156 | rlwimi r8, r10, EPC_EPID_SHIFT, EPC_EPID | ||
| 157 | PPC_STL r23, VCPU_GPR(R23)(r4) | 131 | PPC_STL r23, VCPU_GPR(R23)(r4) |
| 158 | PPC_STL r24, VCPU_GPR(R24)(r4) | 132 | PPC_STL r24, VCPU_GPR(R24)(r4) |
| 159 | PPC_STL r25, VCPU_GPR(R25)(r4) | 133 | PPC_STL r25, VCPU_GPR(R25)(r4) |
| @@ -163,33 +137,15 @@ | |||
| 163 | PPC_STL r29, VCPU_GPR(R29)(r4) | 137 | PPC_STL r29, VCPU_GPR(R29)(r4) |
| 164 | PPC_STL r30, VCPU_GPR(R30)(r4) | 138 | PPC_STL r30, VCPU_GPR(R30)(r4) |
| 165 | PPC_STL r31, VCPU_GPR(R31)(r4) | 139 | PPC_STL r31, VCPU_GPR(R31)(r4) |
| 166 | mtspr SPRN_EPLC, r8 | ||
| 167 | |||
| 168 | /* disable preemption, so we are sure we hit the fixup handler */ | ||
| 169 | CURRENT_THREAD_INFO(r8, r1) | ||
| 170 | li r7, 1 | ||
| 171 | stw r7, TI_PREEMPT(r8) | ||
| 172 | |||
| 173 | isync | ||
| 174 | 140 | ||
| 175 | /* | 141 | /* |
| 176 | * In case the read goes wrong, we catch it and write an invalid value | 142 | * We don't use external PID support. lwepx faults would need to be |
| 177 | * in LAST_INST instead. | 143 | * handled by KVM and this implies aditional code in DO_KVM (for |
| 144 | * DTB_MISS, DSI and LRAT) to check ESR[EPID] and EPLC[EGS] which | ||
| 145 | * is too intrusive for the host. Get last instuction in | ||
| 146 | * kvmppc_get_last_inst(). | ||
| 178 | */ | 147 | */ |
| 179 | 1: lwepx r9, 0, r5 | 148 | li r9, KVM_INST_FETCH_FAILED |
| 180 | 2: | ||
| 181 | .section .fixup, "ax" | ||
| 182 | 3: li r9, KVM_INST_FETCH_FAILED | ||
| 183 | b 2b | ||
| 184 | .previous | ||
| 185 | .section __ex_table,"a" | ||
| 186 | PPC_LONG_ALIGN | ||
| 187 | PPC_LONG 1b,3b | ||
| 188 | .previous | ||
| 189 | |||
| 190 | mtspr SPRN_EPLC, r3 | ||
| 191 | li r7, 0 | ||
| 192 | stw r7, TI_PREEMPT(r8) | ||
| 193 | stw r9, VCPU_LAST_INST(r4) | 149 | stw r9, VCPU_LAST_INST(r4) |
| 194 | .endif | 150 | .endif |
| 195 | 151 | ||
| @@ -441,6 +397,7 @@ _GLOBAL(kvmppc_resume_host) | |||
| 441 | #ifdef CONFIG_64BIT | 397 | #ifdef CONFIG_64BIT |
| 442 | PPC_LL r3, PACA_SPRG_VDSO(r13) | 398 | PPC_LL r3, PACA_SPRG_VDSO(r13) |
| 443 | #endif | 399 | #endif |
| 400 | mfspr r5, SPRN_SPRG9 | ||
| 444 | PPC_STD(r6, VCPU_SHARED_SPRG4, r11) | 401 | PPC_STD(r6, VCPU_SHARED_SPRG4, r11) |
| 445 | mfspr r8, SPRN_SPRG6 | 402 | mfspr r8, SPRN_SPRG6 |
| 446 | PPC_STD(r7, VCPU_SHARED_SPRG5, r11) | 403 | PPC_STD(r7, VCPU_SHARED_SPRG5, r11) |
| @@ -448,6 +405,7 @@ _GLOBAL(kvmppc_resume_host) | |||
| 448 | #ifdef CONFIG_64BIT | 405 | #ifdef CONFIG_64BIT |
| 449 | mtspr SPRN_SPRG_VDSO_WRITE, r3 | 406 | mtspr SPRN_SPRG_VDSO_WRITE, r3 |
| 450 | #endif | 407 | #endif |
| 408 | PPC_STD(r5, VCPU_SPRG9, r4) | ||
| 451 | PPC_STD(r8, VCPU_SHARED_SPRG6, r11) | 409 | PPC_STD(r8, VCPU_SHARED_SPRG6, r11) |
| 452 | mfxer r3 | 410 | mfxer r3 |
| 453 | PPC_STD(r9, VCPU_SHARED_SPRG7, r11) | 411 | PPC_STD(r9, VCPU_SHARED_SPRG7, r11) |
| @@ -682,7 +640,9 @@ lightweight_exit: | |||
| 682 | mtspr SPRN_SPRG5W, r6 | 640 | mtspr SPRN_SPRG5W, r6 |
| 683 | PPC_LD(r8, VCPU_SHARED_SPRG7, r11) | 641 | PPC_LD(r8, VCPU_SHARED_SPRG7, r11) |
| 684 | mtspr SPRN_SPRG6W, r7 | 642 | mtspr SPRN_SPRG6W, r7 |
| 643 | PPC_LD(r5, VCPU_SPRG9, r4) | ||
| 685 | mtspr SPRN_SPRG7W, r8 | 644 | mtspr SPRN_SPRG7W, r8 |
| 645 | mtspr SPRN_SPRG9, r5 | ||
| 686 | 646 | ||
| 687 | /* Load some guest volatiles. */ | 647 | /* Load some guest volatiles. */ |
| 688 | PPC_LL r3, VCPU_LR(r4) | 648 | PPC_LL r3, VCPU_LR(r4) |
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c index 002d51764143..c99c40e9182a 100644 --- a/arch/powerpc/kvm/e500_emulate.c +++ b/arch/powerpc/kvm/e500_emulate.c | |||
| @@ -250,6 +250,14 @@ int kvmppc_core_emulate_mtspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong spr_va | |||
| 250 | spr_val); | 250 | spr_val); |
| 251 | break; | 251 | break; |
| 252 | 252 | ||
| 253 | case SPRN_PWRMGTCR0: | ||
| 254 | /* | ||
| 255 | * Guest relies on host power management configurations | ||
| 256 | * Treat the request as a general store | ||
| 257 | */ | ||
| 258 | vcpu->arch.pwrmgtcr0 = spr_val; | ||
| 259 | break; | ||
| 260 | |||
| 253 | /* extra exceptions */ | 261 | /* extra exceptions */ |
| 254 | case SPRN_IVOR32: | 262 | case SPRN_IVOR32: |
| 255 | vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = spr_val; | 263 | vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = spr_val; |
| @@ -368,6 +376,10 @@ int kvmppc_core_emulate_mfspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong *spr_v | |||
| 368 | *spr_val = vcpu->arch.eptcfg; | 376 | *spr_val = vcpu->arch.eptcfg; |
| 369 | break; | 377 | break; |
| 370 | 378 | ||
| 379 | case SPRN_PWRMGTCR0: | ||
| 380 | *spr_val = vcpu->arch.pwrmgtcr0; | ||
| 381 | break; | ||
| 382 | |||
| 371 | /* extra exceptions */ | 383 | /* extra exceptions */ |
| 372 | case SPRN_IVOR32: | 384 | case SPRN_IVOR32: |
| 373 | *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]; | 385 | *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]; |
diff --git a/arch/powerpc/kvm/e500_mmu_host.c b/arch/powerpc/kvm/e500_mmu_host.c index 86903d3f5a03..08f14bb57897 100644 --- a/arch/powerpc/kvm/e500_mmu_host.c +++ b/arch/powerpc/kvm/e500_mmu_host.c | |||
| @@ -107,11 +107,15 @@ static u32 get_host_mas0(unsigned long eaddr) | |||
| 107 | { | 107 | { |
| 108 | unsigned long flags; | 108 | unsigned long flags; |
| 109 | u32 mas0; | 109 | u32 mas0; |
| 110 | u32 mas4; | ||
| 110 | 111 | ||
| 111 | local_irq_save(flags); | 112 | local_irq_save(flags); |
| 112 | mtspr(SPRN_MAS6, 0); | 113 | mtspr(SPRN_MAS6, 0); |
| 114 | mas4 = mfspr(SPRN_MAS4); | ||
| 115 | mtspr(SPRN_MAS4, mas4 & ~MAS4_TLBSEL_MASK); | ||
| 113 | asm volatile("tlbsx 0, %0" : : "b" (eaddr & ~CONFIG_PAGE_OFFSET)); | 116 | asm volatile("tlbsx 0, %0" : : "b" (eaddr & ~CONFIG_PAGE_OFFSET)); |
| 114 | mas0 = mfspr(SPRN_MAS0); | 117 | mas0 = mfspr(SPRN_MAS0); |
| 118 | mtspr(SPRN_MAS4, mas4); | ||
| 115 | local_irq_restore(flags); | 119 | local_irq_restore(flags); |
| 116 | 120 | ||
| 117 | return mas0; | 121 | return mas0; |
| @@ -607,6 +611,104 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 eaddr, gpa_t gpaddr, | |||
| 607 | } | 611 | } |
| 608 | } | 612 | } |
| 609 | 613 | ||
| 614 | #ifdef CONFIG_KVM_BOOKE_HV | ||
| 615 | int kvmppc_load_last_inst(struct kvm_vcpu *vcpu, enum instruction_type type, | ||
| 616 | u32 *instr) | ||
| 617 | { | ||
| 618 | gva_t geaddr; | ||
| 619 | hpa_t addr; | ||
| 620 | hfn_t pfn; | ||
| 621 | hva_t eaddr; | ||
| 622 | u32 mas1, mas2, mas3; | ||
| 623 | u64 mas7_mas3; | ||
| 624 | struct page *page; | ||
| 625 | unsigned int addr_space, psize_shift; | ||
| 626 | bool pr; | ||
| 627 | unsigned long flags; | ||
| 628 | |||
| 629 | /* Search TLB for guest pc to get the real address */ | ||
| 630 | geaddr = kvmppc_get_pc(vcpu); | ||
| 631 | |||
| 632 | addr_space = (vcpu->arch.shared->msr & MSR_IS) >> MSR_IR_LG; | ||
| 633 | |||
| 634 | local_irq_save(flags); | ||
| 635 | mtspr(SPRN_MAS6, (vcpu->arch.pid << MAS6_SPID_SHIFT) | addr_space); | ||
| 636 | mtspr(SPRN_MAS5, MAS5_SGS | vcpu->kvm->arch.lpid); | ||
| 637 | asm volatile("tlbsx 0, %[geaddr]\n" : : | ||
| 638 | [geaddr] "r" (geaddr)); | ||
| 639 | mtspr(SPRN_MAS5, 0); | ||
| 640 | mtspr(SPRN_MAS8, 0); | ||
| 641 | mas1 = mfspr(SPRN_MAS1); | ||
| 642 | mas2 = mfspr(SPRN_MAS2); | ||
| 643 | mas3 = mfspr(SPRN_MAS3); | ||
| 644 | #ifdef CONFIG_64BIT | ||
| 645 | mas7_mas3 = mfspr(SPRN_MAS7_MAS3); | ||
| 646 | #else | ||
| 647 | mas7_mas3 = ((u64)mfspr(SPRN_MAS7) << 32) | mas3; | ||
| 648 | #endif | ||
| 649 | local_irq_restore(flags); | ||
| 650 | |||
| 651 | /* | ||
| 652 | * If the TLB entry for guest pc was evicted, return to the guest. | ||
| 653 | * There are high chances to find a valid TLB entry next time. | ||
| 654 | */ | ||
| 655 | if (!(mas1 & MAS1_VALID)) | ||
| 656 | return EMULATE_AGAIN; | ||
| 657 | |||
| 658 | /* | ||
| 659 | * Another thread may rewrite the TLB entry in parallel, don't | ||
| 660 | * execute from the address if the execute permission is not set | ||
| 661 | */ | ||
| 662 | pr = vcpu->arch.shared->msr & MSR_PR; | ||
| 663 | if (unlikely((pr && !(mas3 & MAS3_UX)) || | ||
| 664 | (!pr && !(mas3 & MAS3_SX)))) { | ||
| 665 | pr_err_ratelimited( | ||
| 666 | "%s: Instuction emulation from guest addres %08lx without execute permission\n", | ||
| 667 | __func__, geaddr); | ||
| 668 | return EMULATE_AGAIN; | ||
| 669 | } | ||
| 670 | |||
| 671 | /* | ||
| 672 | * The real address will be mapped by a cacheable, memory coherent, | ||
| 673 | * write-back page. Check for mismatches when LRAT is used. | ||
| 674 | */ | ||
| 675 | if (has_feature(vcpu, VCPU_FTR_MMU_V2) && | ||
| 676 | unlikely((mas2 & MAS2_I) || (mas2 & MAS2_W) || !(mas2 & MAS2_M))) { | ||
| 677 | pr_err_ratelimited( | ||
| 678 | "%s: Instuction emulation from guest addres %08lx mismatches storage attributes\n", | ||
| 679 | __func__, geaddr); | ||
| 680 | return EMULATE_AGAIN; | ||
| 681 | } | ||
| 682 | |||
| 683 | /* Get pfn */ | ||
| 684 | psize_shift = MAS1_GET_TSIZE(mas1) + 10; | ||
| 685 | addr = (mas7_mas3 & (~0ULL << psize_shift)) | | ||
| 686 | (geaddr & ((1ULL << psize_shift) - 1ULL)); | ||
| 687 | pfn = addr >> PAGE_SHIFT; | ||
| 688 | |||
| 689 | /* Guard against emulation from devices area */ | ||
| 690 | if (unlikely(!page_is_ram(pfn))) { | ||
| 691 | pr_err_ratelimited("%s: Instruction emulation from non-RAM host addres %08llx is not supported\n", | ||
| 692 | __func__, addr); | ||
| 693 | return EMULATE_AGAIN; | ||
| 694 | } | ||
| 695 | |||
| 696 | /* Map a page and get guest's instruction */ | ||
| 697 | page = pfn_to_page(pfn); | ||
| 698 | eaddr = (unsigned long)kmap_atomic(page); | ||
| 699 | *instr = *(u32 *)(eaddr | (unsigned long)(addr & ~PAGE_MASK)); | ||
| 700 | kunmap_atomic((u32 *)eaddr); | ||
| 701 | |||
| 702 | return EMULATE_DONE; | ||
| 703 | } | ||
| 704 | #else | ||
| 705 | int kvmppc_load_last_inst(struct kvm_vcpu *vcpu, enum instruction_type type, | ||
| 706 | u32 *instr) | ||
| 707 | { | ||
| 708 | return EMULATE_AGAIN; | ||
| 709 | } | ||
| 710 | #endif | ||
| 711 | |||
| 610 | /************* MMU Notifiers *************/ | 712 | /************* MMU Notifiers *************/ |
| 611 | 713 | ||
| 612 | int kvm_unmap_hva(struct kvm *kvm, unsigned long hva) | 714 | int kvm_unmap_hva(struct kvm *kvm, unsigned long hva) |
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c index 17e456279224..164bad2a19bf 100644 --- a/arch/powerpc/kvm/e500mc.c +++ b/arch/powerpc/kvm/e500mc.c | |||
| @@ -110,7 +110,7 @@ void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr) | |||
| 110 | { | 110 | { |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | static DEFINE_PER_CPU(struct kvm_vcpu *, last_vcpu_on_cpu); | 113 | static DEFINE_PER_CPU(struct kvm_vcpu *[KVMPPC_NR_LPIDS], last_vcpu_of_lpid); |
| 114 | 114 | ||
| 115 | static void kvmppc_core_vcpu_load_e500mc(struct kvm_vcpu *vcpu, int cpu) | 115 | static void kvmppc_core_vcpu_load_e500mc(struct kvm_vcpu *vcpu, int cpu) |
| 116 | { | 116 | { |
| @@ -141,9 +141,9 @@ static void kvmppc_core_vcpu_load_e500mc(struct kvm_vcpu *vcpu, int cpu) | |||
| 141 | mtspr(SPRN_GESR, vcpu->arch.shared->esr); | 141 | mtspr(SPRN_GESR, vcpu->arch.shared->esr); |
| 142 | 142 | ||
| 143 | if (vcpu->arch.oldpir != mfspr(SPRN_PIR) || | 143 | if (vcpu->arch.oldpir != mfspr(SPRN_PIR) || |
| 144 | __get_cpu_var(last_vcpu_on_cpu) != vcpu) { | 144 | __get_cpu_var(last_vcpu_of_lpid)[vcpu->kvm->arch.lpid] != vcpu) { |
| 145 | kvmppc_e500_tlbil_all(vcpu_e500); | 145 | kvmppc_e500_tlbil_all(vcpu_e500); |
| 146 | __get_cpu_var(last_vcpu_on_cpu) = vcpu; | 146 | __get_cpu_var(last_vcpu_of_lpid)[vcpu->kvm->arch.lpid] = vcpu; |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | kvmppc_load_guest_fp(vcpu); | 149 | kvmppc_load_guest_fp(vcpu); |
| @@ -267,14 +267,32 @@ static int kvmppc_core_set_sregs_e500mc(struct kvm_vcpu *vcpu, | |||
| 267 | static int kvmppc_get_one_reg_e500mc(struct kvm_vcpu *vcpu, u64 id, | 267 | static int kvmppc_get_one_reg_e500mc(struct kvm_vcpu *vcpu, u64 id, |
| 268 | union kvmppc_one_reg *val) | 268 | union kvmppc_one_reg *val) |
| 269 | { | 269 | { |
| 270 | int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val); | 270 | int r = 0; |
| 271 | |||
| 272 | switch (id) { | ||
| 273 | case KVM_REG_PPC_SPRG9: | ||
| 274 | *val = get_reg_val(id, vcpu->arch.sprg9); | ||
| 275 | break; | ||
| 276 | default: | ||
| 277 | r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val); | ||
| 278 | } | ||
| 279 | |||
| 271 | return r; | 280 | return r; |
| 272 | } | 281 | } |
| 273 | 282 | ||
| 274 | static int kvmppc_set_one_reg_e500mc(struct kvm_vcpu *vcpu, u64 id, | 283 | static int kvmppc_set_one_reg_e500mc(struct kvm_vcpu *vcpu, u64 id, |
| 275 | union kvmppc_one_reg *val) | 284 | union kvmppc_one_reg *val) |
| 276 | { | 285 | { |
| 277 | int r = kvmppc_set_one_reg_e500_tlb(vcpu, id, val); | 286 | int r = 0; |
| 287 | |||
| 288 | switch (id) { | ||
| 289 | case KVM_REG_PPC_SPRG9: | ||
| 290 | vcpu->arch.sprg9 = set_reg_val(id, *val); | ||
| 291 | break; | ||
| 292 | default: | ||
| 293 | r = kvmppc_set_one_reg_e500_tlb(vcpu, id, val); | ||
| 294 | } | ||
| 295 | |||
| 278 | return r; | 296 | return r; |
| 279 | } | 297 | } |
| 280 | 298 | ||
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c index da86d9ba3476..e96b50d0bdab 100644 --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c | |||
| @@ -207,36 +207,28 @@ static int kvmppc_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt) | |||
| 207 | return emulated; | 207 | return emulated; |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | /* XXX to do: | ||
| 211 | * lhax | ||
| 212 | * lhaux | ||
| 213 | * lswx | ||
| 214 | * lswi | ||
| 215 | * stswx | ||
| 216 | * stswi | ||
| 217 | * lha | ||
| 218 | * lhau | ||
| 219 | * lmw | ||
| 220 | * stmw | ||
| 221 | * | ||
| 222 | */ | ||
| 223 | /* XXX Should probably auto-generate instruction decoding for a particular core | 210 | /* XXX Should probably auto-generate instruction decoding for a particular core |
| 224 | * from opcode tables in the future. */ | 211 | * from opcode tables in the future. */ |
| 225 | int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) | 212 | int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) |
| 226 | { | 213 | { |
| 227 | u32 inst = kvmppc_get_last_inst(vcpu); | 214 | u32 inst; |
| 228 | int ra = get_ra(inst); | 215 | int rs, rt, sprn; |
| 229 | int rs = get_rs(inst); | 216 | enum emulation_result emulated; |
| 230 | int rt = get_rt(inst); | ||
| 231 | int sprn = get_sprn(inst); | ||
| 232 | enum emulation_result emulated = EMULATE_DONE; | ||
| 233 | int advance = 1; | 217 | int advance = 1; |
| 234 | 218 | ||
| 235 | /* this default type might be overwritten by subcategories */ | 219 | /* this default type might be overwritten by subcategories */ |
| 236 | kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS); | 220 | kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS); |
| 237 | 221 | ||
| 222 | emulated = kvmppc_get_last_inst(vcpu, false, &inst); | ||
| 223 | if (emulated != EMULATE_DONE) | ||
| 224 | return emulated; | ||
| 225 | |||
| 238 | pr_debug("Emulating opcode %d / %d\n", get_op(inst), get_xop(inst)); | 226 | pr_debug("Emulating opcode %d / %d\n", get_op(inst), get_xop(inst)); |
| 239 | 227 | ||
| 228 | rs = get_rs(inst); | ||
| 229 | rt = get_rt(inst); | ||
| 230 | sprn = get_sprn(inst); | ||
| 231 | |||
| 240 | switch (get_op(inst)) { | 232 | switch (get_op(inst)) { |
| 241 | case OP_TRAP: | 233 | case OP_TRAP: |
| 242 | #ifdef CONFIG_PPC_BOOK3S | 234 | #ifdef CONFIG_PPC_BOOK3S |
| @@ -264,200 +256,24 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
| 264 | #endif | 256 | #endif |
| 265 | advance = 0; | 257 | advance = 0; |
| 266 | break; | 258 | break; |
| 267 | case OP_31_XOP_LWZX: | ||
| 268 | emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); | ||
| 269 | break; | ||
| 270 | |||
| 271 | case OP_31_XOP_LBZX: | ||
| 272 | emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); | ||
| 273 | break; | ||
| 274 | |||
| 275 | case OP_31_XOP_LBZUX: | ||
| 276 | emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); | ||
| 277 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
| 278 | break; | ||
| 279 | |||
| 280 | case OP_31_XOP_STWX: | ||
| 281 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 282 | kvmppc_get_gpr(vcpu, rs), | ||
| 283 | 4, 1); | ||
| 284 | break; | ||
| 285 | |||
| 286 | case OP_31_XOP_STBX: | ||
| 287 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 288 | kvmppc_get_gpr(vcpu, rs), | ||
| 289 | 1, 1); | ||
| 290 | break; | ||
| 291 | |||
| 292 | case OP_31_XOP_STBUX: | ||
| 293 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 294 | kvmppc_get_gpr(vcpu, rs), | ||
| 295 | 1, 1); | ||
| 296 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
| 297 | break; | ||
| 298 | |||
| 299 | case OP_31_XOP_LHAX: | ||
| 300 | emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); | ||
| 301 | break; | ||
| 302 | |||
| 303 | case OP_31_XOP_LHZX: | ||
| 304 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); | ||
| 305 | break; | ||
| 306 | |||
| 307 | case OP_31_XOP_LHZUX: | ||
| 308 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); | ||
| 309 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
| 310 | break; | ||
| 311 | 259 | ||
| 312 | case OP_31_XOP_MFSPR: | 260 | case OP_31_XOP_MFSPR: |
| 313 | emulated = kvmppc_emulate_mfspr(vcpu, sprn, rt); | 261 | emulated = kvmppc_emulate_mfspr(vcpu, sprn, rt); |
| 314 | break; | 262 | break; |
| 315 | 263 | ||
| 316 | case OP_31_XOP_STHX: | ||
| 317 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 318 | kvmppc_get_gpr(vcpu, rs), | ||
| 319 | 2, 1); | ||
| 320 | break; | ||
| 321 | |||
| 322 | case OP_31_XOP_STHUX: | ||
| 323 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 324 | kvmppc_get_gpr(vcpu, rs), | ||
| 325 | 2, 1); | ||
| 326 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
| 327 | break; | ||
| 328 | |||
| 329 | case OP_31_XOP_MTSPR: | 264 | case OP_31_XOP_MTSPR: |
| 330 | emulated = kvmppc_emulate_mtspr(vcpu, sprn, rs); | 265 | emulated = kvmppc_emulate_mtspr(vcpu, sprn, rs); |
| 331 | break; | 266 | break; |
| 332 | 267 | ||
| 333 | case OP_31_XOP_DCBST: | ||
| 334 | case OP_31_XOP_DCBF: | ||
| 335 | case OP_31_XOP_DCBI: | ||
| 336 | /* Do nothing. The guest is performing dcbi because | ||
| 337 | * hardware DMA is not snooped by the dcache, but | ||
| 338 | * emulated DMA either goes through the dcache as | ||
| 339 | * normal writes, or the host kernel has handled dcache | ||
| 340 | * coherence. */ | ||
| 341 | break; | ||
| 342 | |||
| 343 | case OP_31_XOP_LWBRX: | ||
| 344 | emulated = kvmppc_handle_load(run, vcpu, rt, 4, 0); | ||
| 345 | break; | ||
| 346 | |||
| 347 | case OP_31_XOP_TLBSYNC: | 268 | case OP_31_XOP_TLBSYNC: |
| 348 | break; | 269 | break; |
| 349 | 270 | ||
| 350 | case OP_31_XOP_STWBRX: | ||
| 351 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 352 | kvmppc_get_gpr(vcpu, rs), | ||
| 353 | 4, 0); | ||
| 354 | break; | ||
| 355 | |||
| 356 | case OP_31_XOP_LHBRX: | ||
| 357 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 0); | ||
| 358 | break; | ||
| 359 | |||
| 360 | case OP_31_XOP_STHBRX: | ||
| 361 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 362 | kvmppc_get_gpr(vcpu, rs), | ||
| 363 | 2, 0); | ||
| 364 | break; | ||
| 365 | |||
| 366 | default: | 271 | default: |
| 367 | /* Attempt core-specific emulation below. */ | 272 | /* Attempt core-specific emulation below. */ |
| 368 | emulated = EMULATE_FAIL; | 273 | emulated = EMULATE_FAIL; |
| 369 | } | 274 | } |
| 370 | break; | 275 | break; |
| 371 | 276 | ||
| 372 | case OP_LWZ: | ||
| 373 | emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); | ||
| 374 | break; | ||
| 375 | |||
| 376 | /* TBD: Add support for other 64 bit load variants like ldu, ldux, ldx etc. */ | ||
| 377 | case OP_LD: | ||
| 378 | rt = get_rt(inst); | ||
| 379 | emulated = kvmppc_handle_load(run, vcpu, rt, 8, 1); | ||
| 380 | break; | ||
| 381 | |||
| 382 | case OP_LWZU: | ||
| 383 | emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); | ||
| 384 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
| 385 | break; | ||
| 386 | |||
| 387 | case OP_LBZ: | ||
| 388 | emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); | ||
| 389 | break; | ||
| 390 | |||
| 391 | case OP_LBZU: | ||
| 392 | emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); | ||
| 393 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
| 394 | break; | ||
| 395 | |||
| 396 | case OP_STW: | ||
| 397 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 398 | kvmppc_get_gpr(vcpu, rs), | ||
| 399 | 4, 1); | ||
| 400 | break; | ||
| 401 | |||
| 402 | /* TBD: Add support for other 64 bit store variants like stdu, stdux, stdx etc. */ | ||
| 403 | case OP_STD: | ||
| 404 | rs = get_rs(inst); | ||
| 405 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 406 | kvmppc_get_gpr(vcpu, rs), | ||
| 407 | 8, 1); | ||
| 408 | break; | ||
| 409 | |||
| 410 | case OP_STWU: | ||
| 411 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 412 | kvmppc_get_gpr(vcpu, rs), | ||
| 413 | 4, 1); | ||
| 414 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
| 415 | break; | ||
| 416 | |||
| 417 | case OP_STB: | ||
| 418 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 419 | kvmppc_get_gpr(vcpu, rs), | ||
| 420 | 1, 1); | ||
| 421 | break; | ||
| 422 | |||
| 423 | case OP_STBU: | ||
| 424 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 425 | kvmppc_get_gpr(vcpu, rs), | ||
| 426 | 1, 1); | ||
| 427 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
| 428 | break; | ||
| 429 | |||
| 430 | case OP_LHZ: | ||
| 431 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); | ||
| 432 | break; | ||
| 433 | |||
| 434 | case OP_LHZU: | ||
| 435 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); | ||
| 436 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
| 437 | break; | ||
| 438 | |||
| 439 | case OP_LHA: | ||
| 440 | emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); | ||
| 441 | break; | ||
| 442 | |||
| 443 | case OP_LHAU: | ||
| 444 | emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); | ||
| 445 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
| 446 | break; | ||
| 447 | |||
| 448 | case OP_STH: | ||
| 449 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 450 | kvmppc_get_gpr(vcpu, rs), | ||
| 451 | 2, 1); | ||
| 452 | break; | ||
| 453 | |||
| 454 | case OP_STHU: | ||
| 455 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 456 | kvmppc_get_gpr(vcpu, rs), | ||
| 457 | 2, 1); | ||
| 458 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
| 459 | break; | ||
| 460 | |||
| 461 | default: | 277 | default: |
| 462 | emulated = EMULATE_FAIL; | 278 | emulated = EMULATE_FAIL; |
| 463 | } | 279 | } |
diff --git a/arch/powerpc/kvm/emulate_loadstore.c b/arch/powerpc/kvm/emulate_loadstore.c new file mode 100644 index 000000000000..0de4ffa175a9 --- /dev/null +++ b/arch/powerpc/kvm/emulate_loadstore.c | |||
| @@ -0,0 +1,272 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify | ||
| 3 | * it under the terms of the GNU General Public License, version 2, as | ||
| 4 | * published by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * This program is distributed in the hope that it will be useful, | ||
| 7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 9 | * GNU General Public License for more details. | ||
| 10 | * | ||
| 11 | * You should have received a copy of the GNU General Public License | ||
| 12 | * along with this program; if not, write to the Free Software | ||
| 13 | * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 14 | * | ||
| 15 | * Copyright IBM Corp. 2007 | ||
| 16 | * Copyright 2011 Freescale Semiconductor, Inc. | ||
| 17 | * | ||
| 18 | * Authors: Hollis Blanchard <hollisb@us.ibm.com> | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/jiffies.h> | ||
| 22 | #include <linux/hrtimer.h> | ||
| 23 | #include <linux/types.h> | ||
| 24 | #include <linux/string.h> | ||
| 25 | #include <linux/kvm_host.h> | ||
| 26 | #include <linux/clockchips.h> | ||
| 27 | |||
| 28 | #include <asm/reg.h> | ||
| 29 | #include <asm/time.h> | ||
| 30 | #include <asm/byteorder.h> | ||
| 31 | #include <asm/kvm_ppc.h> | ||
| 32 | #include <asm/disassemble.h> | ||
| 33 | #include <asm/ppc-opcode.h> | ||
| 34 | #include "timing.h" | ||
| 35 | #include "trace.h" | ||
| 36 | |||
| 37 | /* XXX to do: | ||
| 38 | * lhax | ||
| 39 | * lhaux | ||
| 40 | * lswx | ||
| 41 | * lswi | ||
| 42 | * stswx | ||
| 43 | * stswi | ||
| 44 | * lha | ||
| 45 | * lhau | ||
| 46 | * lmw | ||
| 47 | * stmw | ||
| 48 | * | ||
| 49 | */ | ||
| 50 | int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu) | ||
| 51 | { | ||
| 52 | struct kvm_run *run = vcpu->run; | ||
| 53 | u32 inst; | ||
| 54 | int ra, rs, rt; | ||
| 55 | enum emulation_result emulated; | ||
| 56 | int advance = 1; | ||
| 57 | |||
| 58 | /* this default type might be overwritten by subcategories */ | ||
| 59 | kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS); | ||
| 60 | |||
| 61 | emulated = kvmppc_get_last_inst(vcpu, false, &inst); | ||
| 62 | if (emulated != EMULATE_DONE) | ||
| 63 | return emulated; | ||
| 64 | |||
| 65 | ra = get_ra(inst); | ||
| 66 | rs = get_rs(inst); | ||
| 67 | rt = get_rt(inst); | ||
| 68 | |||
| 69 | switch (get_op(inst)) { | ||
| 70 | case 31: | ||
| 71 | switch (get_xop(inst)) { | ||
| 72 | case OP_31_XOP_LWZX: | ||
| 73 | emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); | ||
| 74 | break; | ||
| 75 | |||
| 76 | case OP_31_XOP_LBZX: | ||
| 77 | emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); | ||
| 78 | break; | ||
| 79 | |||
| 80 | case OP_31_XOP_LBZUX: | ||
| 81 | emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); | ||
| 82 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
| 83 | break; | ||
| 84 | |||
| 85 | case OP_31_XOP_STWX: | ||
| 86 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 87 | kvmppc_get_gpr(vcpu, rs), | ||
| 88 | 4, 1); | ||
| 89 | break; | ||
| 90 | |||
| 91 | case OP_31_XOP_STBX: | ||
| 92 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 93 | kvmppc_get_gpr(vcpu, rs), | ||
| 94 | 1, 1); | ||
| 95 | break; | ||
| 96 | |||
| 97 | case OP_31_XOP_STBUX: | ||
| 98 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 99 | kvmppc_get_gpr(vcpu, rs), | ||
| 100 | 1, 1); | ||
| 101 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
| 102 | break; | ||
| 103 | |||
| 104 | case OP_31_XOP_LHAX: | ||
| 105 | emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); | ||
| 106 | break; | ||
| 107 | |||
| 108 | case OP_31_XOP_LHZX: | ||
| 109 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); | ||
| 110 | break; | ||
| 111 | |||
| 112 | case OP_31_XOP_LHZUX: | ||
| 113 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); | ||
| 114 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
| 115 | break; | ||
| 116 | |||
| 117 | case OP_31_XOP_STHX: | ||
| 118 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 119 | kvmppc_get_gpr(vcpu, rs), | ||
| 120 | 2, 1); | ||
| 121 | break; | ||
| 122 | |||
| 123 | case OP_31_XOP_STHUX: | ||
| 124 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 125 | kvmppc_get_gpr(vcpu, rs), | ||
| 126 | 2, 1); | ||
| 127 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
| 128 | break; | ||
| 129 | |||
| 130 | case OP_31_XOP_DCBST: | ||
| 131 | case OP_31_XOP_DCBF: | ||
| 132 | case OP_31_XOP_DCBI: | ||
| 133 | /* Do nothing. The guest is performing dcbi because | ||
| 134 | * hardware DMA is not snooped by the dcache, but | ||
| 135 | * emulated DMA either goes through the dcache as | ||
| 136 | * normal writes, or the host kernel has handled dcache | ||
| 137 | * coherence. */ | ||
| 138 | break; | ||
| 139 | |||
| 140 | case OP_31_XOP_LWBRX: | ||
| 141 | emulated = kvmppc_handle_load(run, vcpu, rt, 4, 0); | ||
| 142 | break; | ||
| 143 | |||
| 144 | case OP_31_XOP_STWBRX: | ||
| 145 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 146 | kvmppc_get_gpr(vcpu, rs), | ||
| 147 | 4, 0); | ||
| 148 | break; | ||
| 149 | |||
| 150 | case OP_31_XOP_LHBRX: | ||
| 151 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 0); | ||
| 152 | break; | ||
| 153 | |||
| 154 | case OP_31_XOP_STHBRX: | ||
| 155 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 156 | kvmppc_get_gpr(vcpu, rs), | ||
| 157 | 2, 0); | ||
| 158 | break; | ||
| 159 | |||
| 160 | default: | ||
| 161 | emulated = EMULATE_FAIL; | ||
| 162 | break; | ||
| 163 | } | ||
| 164 | break; | ||
| 165 | |||
| 166 | case OP_LWZ: | ||
| 167 | emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); | ||
| 168 | break; | ||
| 169 | |||
| 170 | /* TBD: Add support for other 64 bit load variants like ldu, ldux, ldx etc. */ | ||
| 171 | case OP_LD: | ||
| 172 | rt = get_rt(inst); | ||
| 173 | emulated = kvmppc_handle_load(run, vcpu, rt, 8, 1); | ||
| 174 | break; | ||
| 175 | |||
| 176 | case OP_LWZU: | ||
| 177 | emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); | ||
| 178 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
| 179 | break; | ||
| 180 | |||
| 181 | case OP_LBZ: | ||
| 182 | emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); | ||
| 183 | break; | ||
| 184 | |||
| 185 | case OP_LBZU: | ||
| 186 | emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); | ||
| 187 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
| 188 | break; | ||
| 189 | |||
| 190 | case OP_STW: | ||
| 191 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 192 | kvmppc_get_gpr(vcpu, rs), | ||
| 193 | 4, 1); | ||
| 194 | break; | ||
| 195 | |||
| 196 | /* TBD: Add support for other 64 bit store variants like stdu, stdux, stdx etc. */ | ||
| 197 | case OP_STD: | ||
| 198 | rs = get_rs(inst); | ||
| 199 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 200 | kvmppc_get_gpr(vcpu, rs), | ||
| 201 | 8, 1); | ||
| 202 | break; | ||
| 203 | |||
| 204 | case OP_STWU: | ||
| 205 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 206 | kvmppc_get_gpr(vcpu, rs), | ||
| 207 | 4, 1); | ||
| 208 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
| 209 | break; | ||
| 210 | |||
| 211 | case OP_STB: | ||
| 212 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 213 | kvmppc_get_gpr(vcpu, rs), | ||
| 214 | 1, 1); | ||
| 215 | break; | ||
| 216 | |||
| 217 | case OP_STBU: | ||
| 218 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 219 | kvmppc_get_gpr(vcpu, rs), | ||
| 220 | 1, 1); | ||
| 221 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
| 222 | break; | ||
| 223 | |||
| 224 | case OP_LHZ: | ||
| 225 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); | ||
| 226 | break; | ||
| 227 | |||
| 228 | case OP_LHZU: | ||
| 229 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); | ||
| 230 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
| 231 | break; | ||
| 232 | |||
| 233 | case OP_LHA: | ||
| 234 | emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); | ||
| 235 | break; | ||
| 236 | |||
| 237 | case OP_LHAU: | ||
| 238 | emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); | ||
| 239 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
| 240 | break; | ||
| 241 | |||
| 242 | case OP_STH: | ||
| 243 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 244 | kvmppc_get_gpr(vcpu, rs), | ||
| 245 | 2, 1); | ||
| 246 | break; | ||
| 247 | |||
| 248 | case OP_STHU: | ||
| 249 | emulated = kvmppc_handle_store(run, vcpu, | ||
| 250 | kvmppc_get_gpr(vcpu, rs), | ||
| 251 | 2, 1); | ||
| 252 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | ||
| 253 | break; | ||
| 254 | |||
| 255 | default: | ||
| 256 | emulated = EMULATE_FAIL; | ||
| 257 | break; | ||
| 258 | } | ||
| 259 | |||
| 260 | if (emulated == EMULATE_FAIL) { | ||
| 261 | advance = 0; | ||
| 262 | kvmppc_core_queue_program(vcpu, 0); | ||
| 263 | } | ||
| 264 | |||
| 265 | trace_kvm_ppc_instr(inst, kvmppc_get_pc(vcpu), emulated); | ||
| 266 | |||
| 267 | /* Advance past emulated instruction. */ | ||
| 268 | if (advance) | ||
| 269 | kvmppc_set_pc(vcpu, kvmppc_get_pc(vcpu) + 4); | ||
| 270 | |||
| 271 | return emulated; | ||
| 272 | } | ||
diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index b68d0dc9479a..39b3a8f816f2 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c | |||
| @@ -1826,8 +1826,7 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, | |||
| 1826 | return 0; | 1826 | return 0; |
| 1827 | } | 1827 | } |
| 1828 | 1828 | ||
| 1829 | int kvm_set_routing_entry(struct kvm_irq_routing_table *rt, | 1829 | int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e, |
| 1830 | struct kvm_kernel_irq_routing_entry *e, | ||
| 1831 | const struct kvm_irq_routing_entry *ue) | 1830 | const struct kvm_irq_routing_entry *ue) |
| 1832 | { | 1831 | { |
| 1833 | int r = -EINVAL; | 1832 | int r = -EINVAL; |
| @@ -1839,7 +1838,6 @@ int kvm_set_routing_entry(struct kvm_irq_routing_table *rt, | |||
| 1839 | e->irqchip.pin = ue->u.irqchip.pin; | 1838 | e->irqchip.pin = ue->u.irqchip.pin; |
| 1840 | if (e->irqchip.pin >= KVM_IRQCHIP_NUM_PINS) | 1839 | if (e->irqchip.pin >= KVM_IRQCHIP_NUM_PINS) |
| 1841 | goto out; | 1840 | goto out; |
| 1842 | rt->chip[ue->u.irqchip.irqchip][e->irqchip.pin] = ue->gsi; | ||
| 1843 | break; | 1841 | break; |
| 1844 | case KVM_IRQ_ROUTING_MSI: | 1842 | case KVM_IRQ_ROUTING_MSI: |
| 1845 | e->set = kvm_set_msi; | 1843 | e->set = kvm_set_msi; |
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 61c738ab1283..4c79284b58be 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
| @@ -190,6 +190,25 @@ int kvmppc_kvm_pv(struct kvm_vcpu *vcpu) | |||
| 190 | vcpu->arch.magic_page_pa = param1 & ~0xfffULL; | 190 | vcpu->arch.magic_page_pa = param1 & ~0xfffULL; |
| 191 | vcpu->arch.magic_page_ea = param2 & ~0xfffULL; | 191 | vcpu->arch.magic_page_ea = param2 & ~0xfffULL; |
| 192 | 192 | ||
| 193 | #ifdef CONFIG_PPC_64K_PAGES | ||
| 194 | /* | ||
| 195 | * Make sure our 4k magic page is in the same window of a 64k | ||
| 196 | * page within the guest and within the host's page. | ||
| 197 | */ | ||
| 198 | if ((vcpu->arch.magic_page_pa & 0xf000) != | ||
| 199 | ((ulong)vcpu->arch.shared & 0xf000)) { | ||
| 200 | void *old_shared = vcpu->arch.shared; | ||
| 201 | ulong shared = (ulong)vcpu->arch.shared; | ||
| 202 | void *new_shared; | ||
| 203 | |||
| 204 | shared &= PAGE_MASK; | ||
| 205 | shared |= vcpu->arch.magic_page_pa & 0xf000; | ||
| 206 | new_shared = (void*)shared; | ||
| 207 | memcpy(new_shared, old_shared, 0x1000); | ||
| 208 | vcpu->arch.shared = new_shared; | ||
| 209 | } | ||
| 210 | #endif | ||
| 211 | |||
| 193 | r2 = KVM_MAGIC_FEAT_SR | KVM_MAGIC_FEAT_MAS0_TO_SPRG7; | 212 | r2 = KVM_MAGIC_FEAT_SR | KVM_MAGIC_FEAT_MAS0_TO_SPRG7; |
| 194 | 213 | ||
| 195 | r = EV_SUCCESS; | 214 | r = EV_SUCCESS; |
| @@ -198,7 +217,6 @@ int kvmppc_kvm_pv(struct kvm_vcpu *vcpu) | |||
| 198 | case KVM_HCALL_TOKEN(KVM_HC_FEATURES): | 217 | case KVM_HCALL_TOKEN(KVM_HC_FEATURES): |
| 199 | r = EV_SUCCESS; | 218 | r = EV_SUCCESS; |
| 200 | #if defined(CONFIG_PPC_BOOK3S) || defined(CONFIG_KVM_E500V2) | 219 | #if defined(CONFIG_PPC_BOOK3S) || defined(CONFIG_KVM_E500V2) |
| 201 | /* XXX Missing magic page on 44x */ | ||
| 202 | r2 |= (1 << KVM_FEATURE_MAGIC_PAGE); | 220 | r2 |= (1 << KVM_FEATURE_MAGIC_PAGE); |
| 203 | #endif | 221 | #endif |
| 204 | 222 | ||
| @@ -254,13 +272,16 @@ int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
| 254 | enum emulation_result er; | 272 | enum emulation_result er; |
| 255 | int r; | 273 | int r; |
| 256 | 274 | ||
| 257 | er = kvmppc_emulate_instruction(run, vcpu); | 275 | er = kvmppc_emulate_loadstore(vcpu); |
| 258 | switch (er) { | 276 | switch (er) { |
| 259 | case EMULATE_DONE: | 277 | case EMULATE_DONE: |
| 260 | /* Future optimization: only reload non-volatiles if they were | 278 | /* Future optimization: only reload non-volatiles if they were |
| 261 | * actually modified. */ | 279 | * actually modified. */ |
| 262 | r = RESUME_GUEST_NV; | 280 | r = RESUME_GUEST_NV; |
| 263 | break; | 281 | break; |
| 282 | case EMULATE_AGAIN: | ||
| 283 | r = RESUME_GUEST; | ||
| 284 | break; | ||
| 264 | case EMULATE_DO_MMIO: | 285 | case EMULATE_DO_MMIO: |
| 265 | run->exit_reason = KVM_EXIT_MMIO; | 286 | run->exit_reason = KVM_EXIT_MMIO; |
| 266 | /* We must reload nonvolatiles because "update" load/store | 287 | /* We must reload nonvolatiles because "update" load/store |
| @@ -270,11 +291,15 @@ int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
| 270 | r = RESUME_HOST_NV; | 291 | r = RESUME_HOST_NV; |
| 271 | break; | 292 | break; |
| 272 | case EMULATE_FAIL: | 293 | case EMULATE_FAIL: |
| 294 | { | ||
| 295 | u32 last_inst; | ||
| 296 | |||
| 297 | kvmppc_get_last_inst(vcpu, false, &last_inst); | ||
| 273 | /* XXX Deliver Program interrupt to guest. */ | 298 | /* XXX Deliver Program interrupt to guest. */ |
| 274 | printk(KERN_EMERG "%s: emulation failed (%08x)\n", __func__, | 299 | pr_emerg("%s: emulation failed (%08x)\n", __func__, last_inst); |
| 275 | kvmppc_get_last_inst(vcpu)); | ||
| 276 | r = RESUME_HOST; | 300 | r = RESUME_HOST; |
| 277 | break; | 301 | break; |
| 302 | } | ||
| 278 | default: | 303 | default: |
| 279 | WARN_ON(1); | 304 | WARN_ON(1); |
| 280 | r = RESUME_GUEST; | 305 | r = RESUME_GUEST; |
| @@ -284,6 +309,81 @@ int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
| 284 | } | 309 | } |
| 285 | EXPORT_SYMBOL_GPL(kvmppc_emulate_mmio); | 310 | EXPORT_SYMBOL_GPL(kvmppc_emulate_mmio); |
| 286 | 311 | ||
| 312 | int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, | ||
| 313 | bool data) | ||
| 314 | { | ||
| 315 | ulong mp_pa = vcpu->arch.magic_page_pa & KVM_PAM & PAGE_MASK; | ||
| 316 | struct kvmppc_pte pte; | ||
| 317 | int r; | ||
| 318 | |||
| 319 | vcpu->stat.st++; | ||
| 320 | |||
| 321 | r = kvmppc_xlate(vcpu, *eaddr, data ? XLATE_DATA : XLATE_INST, | ||
| 322 | XLATE_WRITE, &pte); | ||
| 323 | if (r < 0) | ||
| 324 | return r; | ||
| 325 | |||
| 326 | *eaddr = pte.raddr; | ||
| 327 | |||
| 328 | if (!pte.may_write) | ||
| 329 | return -EPERM; | ||
| 330 | |||
| 331 | /* Magic page override */ | ||
| 332 | if (kvmppc_supports_magic_page(vcpu) && mp_pa && | ||
| 333 | ((pte.raddr & KVM_PAM & PAGE_MASK) == mp_pa) && | ||
| 334 | !(kvmppc_get_msr(vcpu) & MSR_PR)) { | ||
| 335 | void *magic = vcpu->arch.shared; | ||
| 336 | magic += pte.eaddr & 0xfff; | ||
| 337 | memcpy(magic, ptr, size); | ||
| 338 | return EMULATE_DONE; | ||
| 339 | } | ||
| 340 | |||
| 341 | if (kvm_write_guest(vcpu->kvm, pte.raddr, ptr, size)) | ||
| 342 | return EMULATE_DO_MMIO; | ||
| 343 | |||
| 344 | return EMULATE_DONE; | ||
| 345 | } | ||
| 346 | EXPORT_SYMBOL_GPL(kvmppc_st); | ||
| 347 | |||
| 348 | int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, | ||
| 349 | bool data) | ||
| 350 | { | ||
| 351 | ulong mp_pa = vcpu->arch.magic_page_pa & KVM_PAM & PAGE_MASK; | ||
| 352 | struct kvmppc_pte pte; | ||
| 353 | int rc; | ||
| 354 | |||
| 355 | vcpu->stat.ld++; | ||
| 356 | |||
| 357 | rc = kvmppc_xlate(vcpu, *eaddr, data ? XLATE_DATA : XLATE_INST, | ||
| 358 | XLATE_READ, &pte); | ||
| 359 | if (rc) | ||
| 360 | return rc; | ||
| 361 | |||
| 362 | *eaddr = pte.raddr; | ||
| 363 | |||
| 364 | if (!pte.may_read) | ||
| 365 | return -EPERM; | ||
| 366 | |||
| 367 | if (!data && !pte.may_execute) | ||
| 368 | return -ENOEXEC; | ||
| 369 | |||
| 370 | /* Magic page override */ | ||
| 371 | if (kvmppc_supports_magic_page(vcpu) && mp_pa && | ||
| 372 | ((pte.raddr & KVM_PAM & PAGE_MASK) == mp_pa) && | ||
| 373 | !(kvmppc_get_msr(vcpu) & MSR_PR)) { | ||
| 374 | void *magic = vcpu->arch.shared; | ||
| 375 | magic += pte.eaddr & 0xfff; | ||
| 376 | memcpy(ptr, magic, size); | ||
| 377 | return EMULATE_DONE; | ||
| 378 | } | ||
| 379 | |||
| 380 | if (kvm_read_guest(vcpu->kvm, pte.raddr, ptr, size)) | ||
| 381 | return EMULATE_DO_MMIO; | ||
| 382 | |||
| 383 | return EMULATE_DONE; | ||
| 384 | } | ||
| 385 | EXPORT_SYMBOL_GPL(kvmppc_ld); | ||
| 386 | |||
| 287 | int kvm_arch_hardware_enable(void *garbage) | 387 | int kvm_arch_hardware_enable(void *garbage) |
| 288 | { | 388 | { |
| 289 | return 0; | 389 | return 0; |
| @@ -366,14 +466,20 @@ void kvm_arch_sync_events(struct kvm *kvm) | |||
| 366 | { | 466 | { |
| 367 | } | 467 | } |
| 368 | 468 | ||
| 369 | int kvm_dev_ioctl_check_extension(long ext) | 469 | int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) |
| 370 | { | 470 | { |
| 371 | int r; | 471 | int r; |
| 372 | /* FIXME!! | 472 | /* Assume we're using HV mode when the HV module is loaded */ |
| 373 | * Should some of this be vm ioctl ? is it possible now ? | ||
| 374 | */ | ||
| 375 | int hv_enabled = kvmppc_hv_ops ? 1 : 0; | 473 | int hv_enabled = kvmppc_hv_ops ? 1 : 0; |
| 376 | 474 | ||
| 475 | if (kvm) { | ||
| 476 | /* | ||
| 477 | * Hooray - we know which VM type we're running on. Depend on | ||
| 478 | * that rather than the guess above. | ||
| 479 | */ | ||
| 480 | hv_enabled = is_kvmppc_hv_enabled(kvm); | ||
| 481 | } | ||
| 482 | |||
| 377 | switch (ext) { | 483 | switch (ext) { |
| 378 | #ifdef CONFIG_BOOKE | 484 | #ifdef CONFIG_BOOKE |
| 379 | case KVM_CAP_PPC_BOOKE_SREGS: | 485 | case KVM_CAP_PPC_BOOKE_SREGS: |
| @@ -387,6 +493,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
| 387 | case KVM_CAP_PPC_UNSET_IRQ: | 493 | case KVM_CAP_PPC_UNSET_IRQ: |
| 388 | case KVM_CAP_PPC_IRQ_LEVEL: | 494 | case KVM_CAP_PPC_IRQ_LEVEL: |
| 389 | case KVM_CAP_ENABLE_CAP: | 495 | case KVM_CAP_ENABLE_CAP: |
| 496 | case KVM_CAP_ENABLE_CAP_VM: | ||
| 390 | case KVM_CAP_ONE_REG: | 497 | case KVM_CAP_ONE_REG: |
| 391 | case KVM_CAP_IOEVENTFD: | 498 | case KVM_CAP_IOEVENTFD: |
| 392 | case KVM_CAP_DEVICE_CTRL: | 499 | case KVM_CAP_DEVICE_CTRL: |
| @@ -417,6 +524,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
| 417 | case KVM_CAP_PPC_ALLOC_HTAB: | 524 | case KVM_CAP_PPC_ALLOC_HTAB: |
| 418 | case KVM_CAP_PPC_RTAS: | 525 | case KVM_CAP_PPC_RTAS: |
| 419 | case KVM_CAP_PPC_FIXUP_HCALL: | 526 | case KVM_CAP_PPC_FIXUP_HCALL: |
| 527 | case KVM_CAP_PPC_ENABLE_HCALL: | ||
| 420 | #ifdef CONFIG_KVM_XICS | 528 | #ifdef CONFIG_KVM_XICS |
| 421 | case KVM_CAP_IRQ_XICS: | 529 | case KVM_CAP_IRQ_XICS: |
| 422 | #endif | 530 | #endif |
| @@ -635,12 +743,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) | |||
| 635 | #endif | 743 | #endif |
| 636 | } | 744 | } |
| 637 | 745 | ||
| 638 | static void kvmppc_complete_dcr_load(struct kvm_vcpu *vcpu, | ||
| 639 | struct kvm_run *run) | ||
| 640 | { | ||
| 641 | kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, run->dcr.data); | ||
| 642 | } | ||
| 643 | |||
| 644 | static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, | 746 | static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, |
| 645 | struct kvm_run *run) | 747 | struct kvm_run *run) |
| 646 | { | 748 | { |
| @@ -837,10 +939,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
| 837 | if (!vcpu->mmio_is_write) | 939 | if (!vcpu->mmio_is_write) |
| 838 | kvmppc_complete_mmio_load(vcpu, run); | 940 | kvmppc_complete_mmio_load(vcpu, run); |
| 839 | vcpu->mmio_needed = 0; | 941 | vcpu->mmio_needed = 0; |
| 840 | } else if (vcpu->arch.dcr_needed) { | ||
| 841 | if (!vcpu->arch.dcr_is_write) | ||
| 842 | kvmppc_complete_dcr_load(vcpu, run); | ||
| 843 | vcpu->arch.dcr_needed = 0; | ||
| 844 | } else if (vcpu->arch.osi_needed) { | 942 | } else if (vcpu->arch.osi_needed) { |
| 845 | u64 *gprs = run->osi.gprs; | 943 | u64 *gprs = run->osi.gprs; |
| 846 | int i; | 944 | int i; |
| @@ -1099,6 +1197,42 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_event, | |||
| 1099 | return 0; | 1197 | return 0; |
| 1100 | } | 1198 | } |
| 1101 | 1199 | ||
| 1200 | |||
| 1201 | static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, | ||
| 1202 | struct kvm_enable_cap *cap) | ||
| 1203 | { | ||
| 1204 | int r; | ||
| 1205 | |||
| 1206 | if (cap->flags) | ||
| 1207 | return -EINVAL; | ||
| 1208 | |||
| 1209 | switch (cap->cap) { | ||
| 1210 | #ifdef CONFIG_KVM_BOOK3S_64_HANDLER | ||
| 1211 | case KVM_CAP_PPC_ENABLE_HCALL: { | ||
| 1212 | unsigned long hcall = cap->args[0]; | ||
| 1213 | |||
| 1214 | r = -EINVAL; | ||
| 1215 | if (hcall > MAX_HCALL_OPCODE || (hcall & 3) || | ||
| 1216 | cap->args[1] > 1) | ||
| 1217 | break; | ||
| 1218 | if (!kvmppc_book3s_hcall_implemented(kvm, hcall)) | ||
| 1219 | break; | ||
| 1220 | if (cap->args[1]) | ||
| 1221 | set_bit(hcall / 4, kvm->arch.enabled_hcalls); | ||
| 1222 | else | ||
| 1223 | clear_bit(hcall / 4, kvm->arch.enabled_hcalls); | ||
| 1224 | r = 0; | ||
| 1225 | break; | ||
| 1226 | } | ||
| 1227 | #endif | ||
| 1228 | default: | ||
| 1229 | r = -EINVAL; | ||
| 1230 | break; | ||
| 1231 | } | ||
| 1232 | |||
| 1233 | return r; | ||
| 1234 | } | ||
| 1235 | |||
| 1102 | long kvm_arch_vm_ioctl(struct file *filp, | 1236 | long kvm_arch_vm_ioctl(struct file *filp, |
| 1103 | unsigned int ioctl, unsigned long arg) | 1237 | unsigned int ioctl, unsigned long arg) |
| 1104 | { | 1238 | { |
| @@ -1118,6 +1252,15 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
| 1118 | 1252 | ||
| 1119 | break; | 1253 | break; |
| 1120 | } | 1254 | } |
| 1255 | case KVM_ENABLE_CAP: | ||
| 1256 | { | ||
| 1257 | struct kvm_enable_cap cap; | ||
| 1258 | r = -EFAULT; | ||
| 1259 | if (copy_from_user(&cap, argp, sizeof(cap))) | ||
| 1260 | goto out; | ||
| 1261 | r = kvm_vm_ioctl_enable_cap(kvm, &cap); | ||
| 1262 | break; | ||
| 1263 | } | ||
| 1121 | #ifdef CONFIG_PPC_BOOK3S_64 | 1264 | #ifdef CONFIG_PPC_BOOK3S_64 |
| 1122 | case KVM_CREATE_SPAPR_TCE: { | 1265 | case KVM_CREATE_SPAPR_TCE: { |
| 1123 | struct kvm_create_spapr_tce create_tce; | 1266 | struct kvm_create_spapr_tce create_tce; |
| @@ -1204,3 +1347,5 @@ void kvm_arch_exit(void) | |||
| 1204 | { | 1347 | { |
| 1205 | 1348 | ||
| 1206 | } | 1349 | } |
| 1350 | |||
| 1351 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_ppc_instr); | ||
diff --git a/arch/powerpc/kvm/timing.c b/arch/powerpc/kvm/timing.c index 07b6110a4bb7..e44d2b2ea97e 100644 --- a/arch/powerpc/kvm/timing.c +++ b/arch/powerpc/kvm/timing.c | |||
| @@ -110,7 +110,6 @@ void kvmppc_update_timing_stats(struct kvm_vcpu *vcpu) | |||
| 110 | 110 | ||
| 111 | static const char *kvm_exit_names[__NUMBER_OF_KVM_EXIT_TYPES] = { | 111 | static const char *kvm_exit_names[__NUMBER_OF_KVM_EXIT_TYPES] = { |
| 112 | [MMIO_EXITS] = "MMIO", | 112 | [MMIO_EXITS] = "MMIO", |
| 113 | [DCR_EXITS] = "DCR", | ||
| 114 | [SIGNAL_EXITS] = "SIGNAL", | 113 | [SIGNAL_EXITS] = "SIGNAL", |
| 115 | [ITLB_REAL_MISS_EXITS] = "ITLBREAL", | 114 | [ITLB_REAL_MISS_EXITS] = "ITLBREAL", |
| 116 | [ITLB_VIRT_MISS_EXITS] = "ITLBVIRT", | 115 | [ITLB_VIRT_MISS_EXITS] = "ITLBVIRT", |
diff --git a/arch/powerpc/kvm/timing.h b/arch/powerpc/kvm/timing.h index bf191e72b2d8..3123690c82dc 100644 --- a/arch/powerpc/kvm/timing.h +++ b/arch/powerpc/kvm/timing.h | |||
| @@ -63,9 +63,6 @@ static inline void kvmppc_account_exit_stat(struct kvm_vcpu *vcpu, int type) | |||
| 63 | case EMULATED_INST_EXITS: | 63 | case EMULATED_INST_EXITS: |
| 64 | vcpu->stat.emulated_inst_exits++; | 64 | vcpu->stat.emulated_inst_exits++; |
| 65 | break; | 65 | break; |
| 66 | case DCR_EXITS: | ||
| 67 | vcpu->stat.dcr_exits++; | ||
| 68 | break; | ||
| 69 | case DSI_EXITS: | 66 | case DSI_EXITS: |
| 70 | vcpu->stat.dsi_exits++; | 67 | vcpu->stat.dsi_exits++; |
| 71 | break; | 68 | break; |
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig index 10d529ac9821..646db9c467d1 100644 --- a/arch/s390/kvm/Kconfig +++ b/arch/s390/kvm/Kconfig | |||
| @@ -26,6 +26,7 @@ config KVM | |||
| 26 | select KVM_ASYNC_PF | 26 | select KVM_ASYNC_PF |
| 27 | select KVM_ASYNC_PF_SYNC | 27 | select KVM_ASYNC_PF_SYNC |
| 28 | select HAVE_KVM_IRQCHIP | 28 | select HAVE_KVM_IRQCHIP |
| 29 | select HAVE_KVM_IRQFD | ||
| 29 | select HAVE_KVM_IRQ_ROUTING | 30 | select HAVE_KVM_IRQ_ROUTING |
| 30 | ---help--- | 31 | ---help--- |
| 31 | Support hosting paravirtualized guest machines using the SIE | 32 | Support hosting paravirtualized guest machines using the SIE |
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 92528a0bdda6..f4c819bfc193 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c | |||
| @@ -1556,8 +1556,7 @@ static int set_adapter_int(struct kvm_kernel_irq_routing_entry *e, | |||
| 1556 | return ret; | 1556 | return ret; |
| 1557 | } | 1557 | } |
| 1558 | 1558 | ||
| 1559 | int kvm_set_routing_entry(struct kvm_irq_routing_table *rt, | 1559 | int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e, |
| 1560 | struct kvm_kernel_irq_routing_entry *e, | ||
| 1561 | const struct kvm_irq_routing_entry *ue) | 1560 | const struct kvm_irq_routing_entry *ue) |
| 1562 | { | 1561 | { |
| 1563 | int ret; | 1562 | int ret; |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 339b34a02fb8..ce81eb2ab76a 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
| @@ -146,7 +146,7 @@ long kvm_arch_dev_ioctl(struct file *filp, | |||
| 146 | return -EINVAL; | 146 | return -EINVAL; |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | int kvm_dev_ioctl_check_extension(long ext) | 149 | int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) |
| 150 | { | 150 | { |
| 151 | int r; | 151 | int r; |
| 152 | 152 | ||
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index 287e4c85fff9..f9d16ff56c6b 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig | |||
| @@ -27,6 +27,7 @@ config KVM | |||
| 27 | select MMU_NOTIFIER | 27 | select MMU_NOTIFIER |
| 28 | select ANON_INODES | 28 | select ANON_INODES |
| 29 | select HAVE_KVM_IRQCHIP | 29 | select HAVE_KVM_IRQCHIP |
| 30 | select HAVE_KVM_IRQFD | ||
| 30 | select HAVE_KVM_IRQ_ROUTING | 31 | select HAVE_KVM_IRQ_ROUTING |
| 31 | select HAVE_KVM_EVENTFD | 32 | select HAVE_KVM_EVENTFD |
| 32 | select KVM_APIC_ARCHITECTURE | 33 | select KVM_APIC_ARCHITECTURE |
diff --git a/arch/x86/kvm/irq.c b/arch/x86/kvm/irq.c index bd0da433e6d7..a1ec6a50a05a 100644 --- a/arch/x86/kvm/irq.c +++ b/arch/x86/kvm/irq.c | |||
| @@ -108,7 +108,7 @@ int kvm_cpu_get_interrupt(struct kvm_vcpu *v) | |||
| 108 | 108 | ||
| 109 | vector = kvm_cpu_get_extint(v); | 109 | vector = kvm_cpu_get_extint(v); |
| 110 | 110 | ||
| 111 | if (kvm_apic_vid_enabled(v->kvm) || vector != -1) | 111 | if (vector != -1) |
| 112 | return vector; /* PIC */ | 112 | return vector; /* PIC */ |
| 113 | 113 | ||
| 114 | return kvm_get_apic_interrupt(v); /* APIC */ | 114 | return kvm_get_apic_interrupt(v); /* APIC */ |
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 3855103f71fd..08e8a899e005 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
| @@ -352,25 +352,46 @@ static inline int apic_find_highest_irr(struct kvm_lapic *apic) | |||
| 352 | 352 | ||
| 353 | static inline void apic_clear_irr(int vec, struct kvm_lapic *apic) | 353 | static inline void apic_clear_irr(int vec, struct kvm_lapic *apic) |
| 354 | { | 354 | { |
| 355 | apic->irr_pending = false; | 355 | struct kvm_vcpu *vcpu; |
| 356 | |||
| 357 | vcpu = apic->vcpu; | ||
| 358 | |||
| 356 | apic_clear_vector(vec, apic->regs + APIC_IRR); | 359 | apic_clear_vector(vec, apic->regs + APIC_IRR); |
| 357 | if (apic_search_irr(apic) != -1) | 360 | if (unlikely(kvm_apic_vid_enabled(vcpu->kvm))) |
| 358 | apic->irr_pending = true; | 361 | /* try to update RVI */ |
| 362 | kvm_make_request(KVM_REQ_EVENT, vcpu); | ||
| 363 | else { | ||
| 364 | vec = apic_search_irr(apic); | ||
| 365 | apic->irr_pending = (vec != -1); | ||
| 366 | } | ||
| 359 | } | 367 | } |
| 360 | 368 | ||
| 361 | static inline void apic_set_isr(int vec, struct kvm_lapic *apic) | 369 | static inline void apic_set_isr(int vec, struct kvm_lapic *apic) |
| 362 | { | 370 | { |
| 363 | /* Note that we never get here with APIC virtualization enabled. */ | 371 | struct kvm_vcpu *vcpu; |
| 372 | |||
| 373 | if (__apic_test_and_set_vector(vec, apic->regs + APIC_ISR)) | ||
| 374 | return; | ||
| 375 | |||
| 376 | vcpu = apic->vcpu; | ||
| 364 | 377 | ||
| 365 | if (!__apic_test_and_set_vector(vec, apic->regs + APIC_ISR)) | ||
| 366 | ++apic->isr_count; | ||
| 367 | BUG_ON(apic->isr_count > MAX_APIC_VECTOR); | ||
| 368 | /* | 378 | /* |
| 369 | * ISR (in service register) bit is set when injecting an interrupt. | 379 | * With APIC virtualization enabled, all caching is disabled |
| 370 | * The highest vector is injected. Thus the latest bit set matches | 380 | * because the processor can modify ISR under the hood. Instead |
| 371 | * the highest bit in ISR. | 381 | * just set SVI. |
| 372 | */ | 382 | */ |
| 373 | apic->highest_isr_cache = vec; | 383 | if (unlikely(kvm_apic_vid_enabled(vcpu->kvm))) |
| 384 | kvm_x86_ops->hwapic_isr_update(vcpu->kvm, vec); | ||
| 385 | else { | ||
| 386 | ++apic->isr_count; | ||
| 387 | BUG_ON(apic->isr_count > MAX_APIC_VECTOR); | ||
| 388 | /* | ||
| 389 | * ISR (in service register) bit is set when injecting an interrupt. | ||
| 390 | * The highest vector is injected. Thus the latest bit set matches | ||
| 391 | * the highest bit in ISR. | ||
| 392 | */ | ||
| 393 | apic->highest_isr_cache = vec; | ||
| 394 | } | ||
| 374 | } | 395 | } |
| 375 | 396 | ||
| 376 | static inline int apic_find_highest_isr(struct kvm_lapic *apic) | 397 | static inline int apic_find_highest_isr(struct kvm_lapic *apic) |
| @@ -1627,11 +1648,16 @@ int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu) | |||
| 1627 | int vector = kvm_apic_has_interrupt(vcpu); | 1648 | int vector = kvm_apic_has_interrupt(vcpu); |
| 1628 | struct kvm_lapic *apic = vcpu->arch.apic; | 1649 | struct kvm_lapic *apic = vcpu->arch.apic; |
| 1629 | 1650 | ||
| 1630 | /* Note that we never get here with APIC virtualization enabled. */ | ||
| 1631 | |||
| 1632 | if (vector == -1) | 1651 | if (vector == -1) |
| 1633 | return -1; | 1652 | return -1; |
| 1634 | 1653 | ||
| 1654 | /* | ||
| 1655 | * We get here even with APIC virtualization enabled, if doing | ||
| 1656 | * nested virtualization and L1 runs with the "acknowledge interrupt | ||
| 1657 | * on exit" mode. Then we cannot inject the interrupt via RVI, | ||
| 1658 | * because the process would deliver it through the IDT. | ||
| 1659 | */ | ||
| 1660 | |||
| 1635 | apic_set_isr(vector, apic); | 1661 | apic_set_isr(vector, apic); |
| 1636 | apic_update_ppr(apic); | 1662 | apic_update_ppr(apic); |
| 1637 | apic_clear_irr(vector, apic); | 1663 | apic_clear_irr(vector, apic); |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index e618f34bde2d..bfe11cf124a1 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
| @@ -8754,6 +8754,8 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason, | |||
| 8754 | prepare_vmcs12(vcpu, vmcs12, exit_reason, exit_intr_info, | 8754 | prepare_vmcs12(vcpu, vmcs12, exit_reason, exit_intr_info, |
| 8755 | exit_qualification); | 8755 | exit_qualification); |
| 8756 | 8756 | ||
| 8757 | vmx_load_vmcs01(vcpu); | ||
| 8758 | |||
| 8757 | if ((exit_reason == EXIT_REASON_EXTERNAL_INTERRUPT) | 8759 | if ((exit_reason == EXIT_REASON_EXTERNAL_INTERRUPT) |
| 8758 | && nested_exit_intr_ack_set(vcpu)) { | 8760 | && nested_exit_intr_ack_set(vcpu)) { |
| 8759 | int irq = kvm_cpu_get_interrupt(vcpu); | 8761 | int irq = kvm_cpu_get_interrupt(vcpu); |
| @@ -8769,8 +8771,6 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason, | |||
| 8769 | vmcs12->vm_exit_intr_error_code, | 8771 | vmcs12->vm_exit_intr_error_code, |
| 8770 | KVM_ISA_VMX); | 8772 | KVM_ISA_VMX); |
| 8771 | 8773 | ||
| 8772 | vmx_load_vmcs01(vcpu); | ||
| 8773 | |||
| 8774 | vm_entry_controls_init(vmx, vmcs_read32(VM_ENTRY_CONTROLS)); | 8774 | vm_entry_controls_init(vmx, vmcs_read32(VM_ENTRY_CONTROLS)); |
| 8775 | vm_exit_controls_init(vmx, vmcs_read32(VM_EXIT_CONTROLS)); | 8775 | vm_exit_controls_init(vmx, vmcs_read32(VM_EXIT_CONTROLS)); |
| 8776 | vmx_segment_cache_clear(vmx); | 8776 | vmx_segment_cache_clear(vmx); |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index ca3d760dd581..8f1e22d3b286 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -2636,7 +2636,7 @@ out: | |||
| 2636 | return r; | 2636 | return r; |
| 2637 | } | 2637 | } |
| 2638 | 2638 | ||
| 2639 | int kvm_dev_ioctl_check_extension(long ext) | 2639 | int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) |
| 2640 | { | 2640 | { |
| 2641 | int r; | 2641 | int r; |
| 2642 | 2642 | ||
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h index 6d9aeddc09bf..ad9db6045b2f 100644 --- a/include/kvm/arm_arch_timer.h +++ b/include/kvm/arm_arch_timer.h | |||
| @@ -67,6 +67,10 @@ void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu); | |||
| 67 | void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu); | 67 | void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu); |
| 68 | void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu); | 68 | void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu); |
| 69 | void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu); | 69 | void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu); |
| 70 | |||
| 71 | u64 kvm_arm_timer_get_reg(struct kvm_vcpu *, u64 regid); | ||
| 72 | int kvm_arm_timer_set_reg(struct kvm_vcpu *, u64 regid, u64 value); | ||
| 73 | |||
| 70 | #else | 74 | #else |
| 71 | static inline int kvm_timer_hyp_init(void) | 75 | static inline int kvm_timer_hyp_init(void) |
| 72 | { | 76 | { |
| @@ -84,6 +88,16 @@ static inline void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu) {} | |||
| 84 | static inline void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu) {} | 88 | static inline void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu) {} |
| 85 | static inline void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu) {} | 89 | static inline void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu) {} |
| 86 | static inline void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu) {} | 90 | static inline void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu) {} |
| 91 | |||
| 92 | static inline int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value) | ||
| 93 | { | ||
| 94 | return 0; | ||
| 95 | } | ||
| 96 | |||
| 97 | static inline u64 kvm_arm_timer_get_reg(struct kvm_vcpu *vcpu, u64 regid) | ||
| 98 | { | ||
| 99 | return 0; | ||
| 100 | } | ||
| 87 | #endif | 101 | #endif |
| 88 | 102 | ||
| 89 | #endif | 103 | #endif |
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index f27000f55a83..35b0c121bb65 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h | |||
| @@ -24,7 +24,6 @@ | |||
| 24 | #include <linux/irqreturn.h> | 24 | #include <linux/irqreturn.h> |
| 25 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
| 26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
| 27 | #include <linux/irqchip/arm-gic.h> | ||
| 28 | 27 | ||
| 29 | #define VGIC_NR_IRQS 256 | 28 | #define VGIC_NR_IRQS 256 |
| 30 | #define VGIC_NR_SGIS 16 | 29 | #define VGIC_NR_SGIS 16 |
| @@ -32,7 +31,9 @@ | |||
| 32 | #define VGIC_NR_PRIVATE_IRQS (VGIC_NR_SGIS + VGIC_NR_PPIS) | 31 | #define VGIC_NR_PRIVATE_IRQS (VGIC_NR_SGIS + VGIC_NR_PPIS) |
| 33 | #define VGIC_NR_SHARED_IRQS (VGIC_NR_IRQS - VGIC_NR_PRIVATE_IRQS) | 32 | #define VGIC_NR_SHARED_IRQS (VGIC_NR_IRQS - VGIC_NR_PRIVATE_IRQS) |
| 34 | #define VGIC_MAX_CPUS KVM_MAX_VCPUS | 33 | #define VGIC_MAX_CPUS KVM_MAX_VCPUS |
| 35 | #define VGIC_MAX_LRS (1 << 6) | 34 | |
| 35 | #define VGIC_V2_MAX_LRS (1 << 6) | ||
| 36 | #define VGIC_V3_MAX_LRS 16 | ||
| 36 | 37 | ||
| 37 | /* Sanity checks... */ | 38 | /* Sanity checks... */ |
| 38 | #if (VGIC_MAX_CPUS > 8) | 39 | #if (VGIC_MAX_CPUS > 8) |
| @@ -68,9 +69,62 @@ struct vgic_bytemap { | |||
| 68 | u32 shared[VGIC_NR_SHARED_IRQS / 4]; | 69 | u32 shared[VGIC_NR_SHARED_IRQS / 4]; |
| 69 | }; | 70 | }; |
| 70 | 71 | ||
| 72 | struct kvm_vcpu; | ||
| 73 | |||
| 74 | enum vgic_type { | ||
| 75 | VGIC_V2, /* Good ol' GICv2 */ | ||
| 76 | VGIC_V3, /* New fancy GICv3 */ | ||
| 77 | }; | ||
| 78 | |||
| 79 | #define LR_STATE_PENDING (1 << 0) | ||
| 80 | #define LR_STATE_ACTIVE (1 << 1) | ||
| 81 | #define LR_STATE_MASK (3 << 0) | ||
| 82 | #define LR_EOI_INT (1 << 2) | ||
| 83 | |||
| 84 | struct vgic_lr { | ||
| 85 | u16 irq; | ||
| 86 | u8 source; | ||
| 87 | u8 state; | ||
| 88 | }; | ||
| 89 | |||
| 90 | struct vgic_vmcr { | ||
| 91 | u32 ctlr; | ||
| 92 | u32 abpr; | ||
| 93 | u32 bpr; | ||
| 94 | u32 pmr; | ||
| 95 | }; | ||
| 96 | |||
| 97 | struct vgic_ops { | ||
| 98 | struct vgic_lr (*get_lr)(const struct kvm_vcpu *, int); | ||
| 99 | void (*set_lr)(struct kvm_vcpu *, int, struct vgic_lr); | ||
| 100 | void (*sync_lr_elrsr)(struct kvm_vcpu *, int, struct vgic_lr); | ||
| 101 | u64 (*get_elrsr)(const struct kvm_vcpu *vcpu); | ||
| 102 | u64 (*get_eisr)(const struct kvm_vcpu *vcpu); | ||
| 103 | u32 (*get_interrupt_status)(const struct kvm_vcpu *vcpu); | ||
| 104 | void (*enable_underflow)(struct kvm_vcpu *vcpu); | ||
| 105 | void (*disable_underflow)(struct kvm_vcpu *vcpu); | ||
| 106 | void (*get_vmcr)(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); | ||
| 107 | void (*set_vmcr)(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); | ||
| 108 | void (*enable)(struct kvm_vcpu *vcpu); | ||
| 109 | }; | ||
| 110 | |||
| 111 | struct vgic_params { | ||
| 112 | /* vgic type */ | ||
| 113 | enum vgic_type type; | ||
| 114 | /* Physical address of vgic virtual cpu interface */ | ||
| 115 | phys_addr_t vcpu_base; | ||
| 116 | /* Number of list registers */ | ||
| 117 | u32 nr_lr; | ||
| 118 | /* Interrupt number */ | ||
| 119 | unsigned int maint_irq; | ||
| 120 | /* Virtual control interface base address */ | ||
| 121 | void __iomem *vctrl_base; | ||
| 122 | }; | ||
| 123 | |||
| 71 | struct vgic_dist { | 124 | struct vgic_dist { |
| 72 | #ifdef CONFIG_KVM_ARM_VGIC | 125 | #ifdef CONFIG_KVM_ARM_VGIC |
| 73 | spinlock_t lock; | 126 | spinlock_t lock; |
| 127 | bool in_kernel; | ||
| 74 | bool ready; | 128 | bool ready; |
| 75 | 129 | ||
| 76 | /* Virtual control interface mapping */ | 130 | /* Virtual control interface mapping */ |
| @@ -110,6 +164,29 @@ struct vgic_dist { | |||
| 110 | #endif | 164 | #endif |
| 111 | }; | 165 | }; |
| 112 | 166 | ||
| 167 | struct vgic_v2_cpu_if { | ||
| 168 | u32 vgic_hcr; | ||
| 169 | u32 vgic_vmcr; | ||
| 170 | u32 vgic_misr; /* Saved only */ | ||
| 171 | u32 vgic_eisr[2]; /* Saved only */ | ||
| 172 | u32 vgic_elrsr[2]; /* Saved only */ | ||
| 173 | u32 vgic_apr; | ||
| 174 | u32 vgic_lr[VGIC_V2_MAX_LRS]; | ||
| 175 | }; | ||
| 176 | |||
| 177 | struct vgic_v3_cpu_if { | ||
| 178 | #ifdef CONFIG_ARM_GIC_V3 | ||
| 179 | u32 vgic_hcr; | ||
| 180 | u32 vgic_vmcr; | ||
| 181 | u32 vgic_misr; /* Saved only */ | ||
| 182 | u32 vgic_eisr; /* Saved only */ | ||
| 183 | u32 vgic_elrsr; /* Saved only */ | ||
| 184 | u32 vgic_ap0r[4]; | ||
| 185 | u32 vgic_ap1r[4]; | ||
| 186 | u64 vgic_lr[VGIC_V3_MAX_LRS]; | ||
| 187 | #endif | ||
| 188 | }; | ||
| 189 | |||
| 113 | struct vgic_cpu { | 190 | struct vgic_cpu { |
| 114 | #ifdef CONFIG_KVM_ARM_VGIC | 191 | #ifdef CONFIG_KVM_ARM_VGIC |
| 115 | /* per IRQ to LR mapping */ | 192 | /* per IRQ to LR mapping */ |
| @@ -120,24 +197,24 @@ struct vgic_cpu { | |||
| 120 | DECLARE_BITMAP( pending_shared, VGIC_NR_SHARED_IRQS); | 197 | DECLARE_BITMAP( pending_shared, VGIC_NR_SHARED_IRQS); |
| 121 | 198 | ||
| 122 | /* Bitmap of used/free list registers */ | 199 | /* Bitmap of used/free list registers */ |
| 123 | DECLARE_BITMAP( lr_used, VGIC_MAX_LRS); | 200 | DECLARE_BITMAP( lr_used, VGIC_V2_MAX_LRS); |
| 124 | 201 | ||
| 125 | /* Number of list registers on this CPU */ | 202 | /* Number of list registers on this CPU */ |
| 126 | int nr_lr; | 203 | int nr_lr; |
| 127 | 204 | ||
| 128 | /* CPU vif control registers for world switch */ | 205 | /* CPU vif control registers for world switch */ |
| 129 | u32 vgic_hcr; | 206 | union { |
| 130 | u32 vgic_vmcr; | 207 | struct vgic_v2_cpu_if vgic_v2; |
| 131 | u32 vgic_misr; /* Saved only */ | 208 | struct vgic_v3_cpu_if vgic_v3; |
| 132 | u32 vgic_eisr[2]; /* Saved only */ | 209 | }; |
| 133 | u32 vgic_elrsr[2]; /* Saved only */ | ||
| 134 | u32 vgic_apr; | ||
| 135 | u32 vgic_lr[VGIC_MAX_LRS]; | ||
| 136 | #endif | 210 | #endif |
| 137 | }; | 211 | }; |
| 138 | 212 | ||
| 139 | #define LR_EMPTY 0xff | 213 | #define LR_EMPTY 0xff |
| 140 | 214 | ||
| 215 | #define INT_STATUS_EOI (1 << 0) | ||
| 216 | #define INT_STATUS_UNDERFLOW (1 << 1) | ||
| 217 | |||
| 141 | struct kvm; | 218 | struct kvm; |
| 142 | struct kvm_vcpu; | 219 | struct kvm_vcpu; |
| 143 | struct kvm_run; | 220 | struct kvm_run; |
| @@ -157,9 +234,25 @@ int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); | |||
| 157 | bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run, | 234 | bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run, |
| 158 | struct kvm_exit_mmio *mmio); | 235 | struct kvm_exit_mmio *mmio); |
| 159 | 236 | ||
| 160 | #define irqchip_in_kernel(k) (!!((k)->arch.vgic.vctrl_base)) | 237 | #define irqchip_in_kernel(k) (!!((k)->arch.vgic.in_kernel)) |
| 161 | #define vgic_initialized(k) ((k)->arch.vgic.ready) | 238 | #define vgic_initialized(k) ((k)->arch.vgic.ready) |
| 162 | 239 | ||
| 240 | int vgic_v2_probe(struct device_node *vgic_node, | ||
| 241 | const struct vgic_ops **ops, | ||
| 242 | const struct vgic_params **params); | ||
| 243 | #ifdef CONFIG_ARM_GIC_V3 | ||
| 244 | int vgic_v3_probe(struct device_node *vgic_node, | ||
| 245 | const struct vgic_ops **ops, | ||
| 246 | const struct vgic_params **params); | ||
| 247 | #else | ||
| 248 | static inline int vgic_v3_probe(struct device_node *vgic_node, | ||
| 249 | const struct vgic_ops **ops, | ||
| 250 | const struct vgic_params **params) | ||
| 251 | { | ||
| 252 | return -ENODEV; | ||
| 253 | } | ||
| 254 | #endif | ||
| 255 | |||
| 163 | #else | 256 | #else |
| 164 | static inline int kvm_vgic_hyp_init(void) | 257 | static inline int kvm_vgic_hyp_init(void) |
| 165 | { | 258 | { |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index ec4e3bd83d47..a4c33b34fe3f 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
| @@ -325,24 +325,7 @@ struct kvm_kernel_irq_routing_entry { | |||
| 325 | struct hlist_node link; | 325 | struct hlist_node link; |
| 326 | }; | 326 | }; |
| 327 | 327 | ||
| 328 | #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING | 328 | struct kvm_irq_routing_table; |
| 329 | |||
| 330 | struct kvm_irq_routing_table { | ||
| 331 | int chip[KVM_NR_IRQCHIPS][KVM_IRQCHIP_NUM_PINS]; | ||
| 332 | struct kvm_kernel_irq_routing_entry *rt_entries; | ||
| 333 | u32 nr_rt_entries; | ||
| 334 | /* | ||
| 335 | * Array indexed by gsi. Each entry contains list of irq chips | ||
| 336 | * the gsi is connected to. | ||
| 337 | */ | ||
| 338 | struct hlist_head map[0]; | ||
| 339 | }; | ||
| 340 | |||
| 341 | #else | ||
| 342 | |||
| 343 | struct kvm_irq_routing_table {}; | ||
| 344 | |||
| 345 | #endif | ||
| 346 | 329 | ||
| 347 | #ifndef KVM_PRIVATE_MEM_SLOTS | 330 | #ifndef KVM_PRIVATE_MEM_SLOTS |
| 348 | #define KVM_PRIVATE_MEM_SLOTS 0 | 331 | #define KVM_PRIVATE_MEM_SLOTS 0 |
| @@ -401,11 +384,12 @@ struct kvm { | |||
| 401 | struct mutex irq_lock; | 384 | struct mutex irq_lock; |
| 402 | #ifdef CONFIG_HAVE_KVM_IRQCHIP | 385 | #ifdef CONFIG_HAVE_KVM_IRQCHIP |
| 403 | /* | 386 | /* |
| 404 | * Update side is protected by irq_lock and, | 387 | * Update side is protected by irq_lock. |
| 405 | * if configured, irqfds.lock. | ||
| 406 | */ | 388 | */ |
| 407 | struct kvm_irq_routing_table __rcu *irq_routing; | 389 | struct kvm_irq_routing_table __rcu *irq_routing; |
| 408 | struct hlist_head mask_notifier_list; | 390 | struct hlist_head mask_notifier_list; |
| 391 | #endif | ||
| 392 | #ifdef CONFIG_HAVE_KVM_IRQFD | ||
| 409 | struct hlist_head irq_ack_notifier_list; | 393 | struct hlist_head irq_ack_notifier_list; |
| 410 | #endif | 394 | #endif |
| 411 | 395 | ||
| @@ -455,7 +439,7 @@ void kvm_vcpu_uninit(struct kvm_vcpu *vcpu); | |||
| 455 | int __must_check vcpu_load(struct kvm_vcpu *vcpu); | 439 | int __must_check vcpu_load(struct kvm_vcpu *vcpu); |
| 456 | void vcpu_put(struct kvm_vcpu *vcpu); | 440 | void vcpu_put(struct kvm_vcpu *vcpu); |
| 457 | 441 | ||
| 458 | #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING | 442 | #ifdef CONFIG_HAVE_KVM_IRQFD |
| 459 | int kvm_irqfd_init(void); | 443 | int kvm_irqfd_init(void); |
| 460 | void kvm_irqfd_exit(void); | 444 | void kvm_irqfd_exit(void); |
| 461 | #else | 445 | #else |
| @@ -602,7 +586,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp, | |||
| 602 | unsigned int ioctl, unsigned long arg); | 586 | unsigned int ioctl, unsigned long arg); |
| 603 | int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf); | 587 | int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf); |
| 604 | 588 | ||
| 605 | int kvm_dev_ioctl_check_extension(long ext); | 589 | int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext); |
| 606 | 590 | ||
| 607 | int kvm_get_dirty_log(struct kvm *kvm, | 591 | int kvm_get_dirty_log(struct kvm *kvm, |
| 608 | struct kvm_dirty_log *log, int *is_dirty); | 592 | struct kvm_dirty_log *log, int *is_dirty); |
| @@ -752,6 +736,10 @@ void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq, | |||
| 752 | void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin, | 736 | void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin, |
| 753 | bool mask); | 737 | bool mask); |
| 754 | 738 | ||
| 739 | int kvm_irq_map_gsi(struct kvm *kvm, | ||
| 740 | struct kvm_kernel_irq_routing_entry *entries, int gsi); | ||
| 741 | int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin); | ||
| 742 | |||
| 755 | int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level, | 743 | int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level, |
| 756 | bool line_status); | 744 | bool line_status); |
| 757 | int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level); | 745 | int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level); |
| @@ -942,28 +930,27 @@ int kvm_set_irq_routing(struct kvm *kvm, | |||
| 942 | const struct kvm_irq_routing_entry *entries, | 930 | const struct kvm_irq_routing_entry *entries, |
| 943 | unsigned nr, | 931 | unsigned nr, |
| 944 | unsigned flags); | 932 | unsigned flags); |
| 945 | int kvm_set_routing_entry(struct kvm_irq_routing_table *rt, | 933 | int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e, |
| 946 | struct kvm_kernel_irq_routing_entry *e, | ||
| 947 | const struct kvm_irq_routing_entry *ue); | 934 | const struct kvm_irq_routing_entry *ue); |
| 948 | void kvm_free_irq_routing(struct kvm *kvm); | 935 | void kvm_free_irq_routing(struct kvm *kvm); |
| 949 | 936 | ||
| 950 | int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi); | ||
| 951 | |||
| 952 | #else | 937 | #else |
| 953 | 938 | ||
| 954 | static inline void kvm_free_irq_routing(struct kvm *kvm) {} | 939 | static inline void kvm_free_irq_routing(struct kvm *kvm) {} |
| 955 | 940 | ||
| 956 | #endif | 941 | #endif |
| 957 | 942 | ||
| 943 | int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi); | ||
| 944 | |||
| 958 | #ifdef CONFIG_HAVE_KVM_EVENTFD | 945 | #ifdef CONFIG_HAVE_KVM_EVENTFD |
| 959 | 946 | ||
| 960 | void kvm_eventfd_init(struct kvm *kvm); | 947 | void kvm_eventfd_init(struct kvm *kvm); |
| 961 | int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args); | 948 | int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args); |
| 962 | 949 | ||
| 963 | #ifdef CONFIG_HAVE_KVM_IRQCHIP | 950 | #ifdef CONFIG_HAVE_KVM_IRQFD |
| 964 | int kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args); | 951 | int kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args); |
| 965 | void kvm_irqfd_release(struct kvm *kvm); | 952 | void kvm_irqfd_release(struct kvm *kvm); |
| 966 | void kvm_irq_routing_update(struct kvm *, struct kvm_irq_routing_table *); | 953 | void kvm_irq_routing_update(struct kvm *); |
| 967 | #else | 954 | #else |
| 968 | static inline int kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args) | 955 | static inline int kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args) |
| 969 | { | 956 | { |
| @@ -985,10 +972,8 @@ static inline int kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args) | |||
| 985 | static inline void kvm_irqfd_release(struct kvm *kvm) {} | 972 | static inline void kvm_irqfd_release(struct kvm *kvm) {} |
| 986 | 973 | ||
| 987 | #ifdef CONFIG_HAVE_KVM_IRQCHIP | 974 | #ifdef CONFIG_HAVE_KVM_IRQCHIP |
| 988 | static inline void kvm_irq_routing_update(struct kvm *kvm, | 975 | static inline void kvm_irq_routing_update(struct kvm *kvm) |
| 989 | struct kvm_irq_routing_table *irq_rt) | ||
| 990 | { | 976 | { |
| 991 | rcu_assign_pointer(kvm->irq_routing, irq_rt); | ||
| 992 | } | 977 | } |
| 993 | #endif | 978 | #endif |
| 994 | 979 | ||
diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h index 131a0bda7aec..908925ace776 100644 --- a/include/trace/events/kvm.h +++ b/include/trace/events/kvm.h | |||
| @@ -37,7 +37,7 @@ TRACE_EVENT(kvm_userspace_exit, | |||
| 37 | __entry->errno < 0 ? -__entry->errno : __entry->reason) | 37 | __entry->errno < 0 ? -__entry->errno : __entry->reason) |
| 38 | ); | 38 | ); |
| 39 | 39 | ||
| 40 | #if defined(CONFIG_HAVE_KVM_IRQCHIP) | 40 | #if defined(CONFIG_HAVE_KVM_IRQFD) |
| 41 | TRACE_EVENT(kvm_set_irq, | 41 | TRACE_EVENT(kvm_set_irq, |
| 42 | TP_PROTO(unsigned int gsi, int level, int irq_source_id), | 42 | TP_PROTO(unsigned int gsi, int level, int irq_source_id), |
| 43 | TP_ARGS(gsi, level, irq_source_id), | 43 | TP_ARGS(gsi, level, irq_source_id), |
| @@ -57,7 +57,7 @@ TRACE_EVENT(kvm_set_irq, | |||
| 57 | TP_printk("gsi %u level %d source %d", | 57 | TP_printk("gsi %u level %d source %d", |
| 58 | __entry->gsi, __entry->level, __entry->irq_source_id) | 58 | __entry->gsi, __entry->level, __entry->irq_source_id) |
| 59 | ); | 59 | ); |
| 60 | #endif | 60 | #endif /* defined(CONFIG_HAVE_KVM_IRQFD) */ |
| 61 | 61 | ||
| 62 | #if defined(__KVM_HAVE_IOAPIC) | 62 | #if defined(__KVM_HAVE_IOAPIC) |
| 63 | #define kvm_deliver_mode \ | 63 | #define kvm_deliver_mode \ |
| @@ -124,7 +124,7 @@ TRACE_EVENT(kvm_msi_set_irq, | |||
| 124 | 124 | ||
| 125 | #endif /* defined(__KVM_HAVE_IOAPIC) */ | 125 | #endif /* defined(__KVM_HAVE_IOAPIC) */ |
| 126 | 126 | ||
| 127 | #if defined(CONFIG_HAVE_KVM_IRQCHIP) | 127 | #if defined(CONFIG_HAVE_KVM_IRQFD) |
| 128 | 128 | ||
| 129 | TRACE_EVENT(kvm_ack_irq, | 129 | TRACE_EVENT(kvm_ack_irq, |
| 130 | TP_PROTO(unsigned int irqchip, unsigned int pin), | 130 | TP_PROTO(unsigned int irqchip, unsigned int pin), |
| @@ -149,7 +149,7 @@ TRACE_EVENT(kvm_ack_irq, | |||
| 149 | #endif | 149 | #endif |
| 150 | ); | 150 | ); |
| 151 | 151 | ||
| 152 | #endif /* defined(CONFIG_HAVE_KVM_IRQCHIP) */ | 152 | #endif /* defined(CONFIG_HAVE_KVM_IRQFD) */ |
| 153 | 153 | ||
| 154 | 154 | ||
| 155 | 155 | ||
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 9b744af871d7..cf3a2ff440e4 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h | |||
| @@ -162,7 +162,7 @@ struct kvm_pit_config { | |||
| 162 | #define KVM_EXIT_TPR_ACCESS 12 | 162 | #define KVM_EXIT_TPR_ACCESS 12 |
| 163 | #define KVM_EXIT_S390_SIEIC 13 | 163 | #define KVM_EXIT_S390_SIEIC 13 |
| 164 | #define KVM_EXIT_S390_RESET 14 | 164 | #define KVM_EXIT_S390_RESET 14 |
| 165 | #define KVM_EXIT_DCR 15 | 165 | #define KVM_EXIT_DCR 15 /* deprecated */ |
| 166 | #define KVM_EXIT_NMI 16 | 166 | #define KVM_EXIT_NMI 16 |
| 167 | #define KVM_EXIT_INTERNAL_ERROR 17 | 167 | #define KVM_EXIT_INTERNAL_ERROR 17 |
| 168 | #define KVM_EXIT_OSI 18 | 168 | #define KVM_EXIT_OSI 18 |
| @@ -268,7 +268,7 @@ struct kvm_run { | |||
| 268 | __u64 trans_exc_code; | 268 | __u64 trans_exc_code; |
| 269 | __u32 pgm_code; | 269 | __u32 pgm_code; |
| 270 | } s390_ucontrol; | 270 | } s390_ucontrol; |
| 271 | /* KVM_EXIT_DCR */ | 271 | /* KVM_EXIT_DCR (deprecated) */ |
| 272 | struct { | 272 | struct { |
| 273 | __u32 dcrn; | 273 | __u32 dcrn; |
| 274 | __u32 data; | 274 | __u32 data; |
| @@ -763,6 +763,8 @@ struct kvm_ppc_smmu_info { | |||
| 763 | #define KVM_CAP_VM_ATTRIBUTES 101 | 763 | #define KVM_CAP_VM_ATTRIBUTES 101 |
| 764 | #define KVM_CAP_ARM_PSCI_0_2 102 | 764 | #define KVM_CAP_ARM_PSCI_0_2 102 |
| 765 | #define KVM_CAP_PPC_FIXUP_HCALL 103 | 765 | #define KVM_CAP_PPC_FIXUP_HCALL 103 |
| 766 | #define KVM_CAP_PPC_ENABLE_HCALL 104 | ||
| 767 | #define KVM_CAP_CHECK_EXTENSION_VM 105 | ||
| 766 | 768 | ||
| 767 | #ifdef KVM_CAP_IRQ_ROUTING | 769 | #ifdef KVM_CAP_IRQ_ROUTING |
| 768 | 770 | ||
diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig index 13f2d19793e3..fc0c5e603eb4 100644 --- a/virt/kvm/Kconfig +++ b/virt/kvm/Kconfig | |||
| @@ -6,6 +6,9 @@ config HAVE_KVM | |||
| 6 | config HAVE_KVM_IRQCHIP | 6 | config HAVE_KVM_IRQCHIP |
| 7 | bool | 7 | bool |
| 8 | 8 | ||
| 9 | config HAVE_KVM_IRQFD | ||
| 10 | bool | ||
| 11 | |||
| 9 | config HAVE_KVM_IRQ_ROUTING | 12 | config HAVE_KVM_IRQ_ROUTING |
| 10 | bool | 13 | bool |
| 11 | 14 | ||
diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c new file mode 100644 index 000000000000..01124ef3690a --- /dev/null +++ b/virt/kvm/arm/vgic-v2.c | |||
| @@ -0,0 +1,265 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2012,2013 ARM Limited, All Rights Reserved. | ||
| 3 | * Author: Marc Zyngier <marc.zyngier@arm.com> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/cpu.h> | ||
| 19 | #include <linux/kvm.h> | ||
| 20 | #include <linux/kvm_host.h> | ||
| 21 | #include <linux/interrupt.h> | ||
| 22 | #include <linux/io.h> | ||
| 23 | #include <linux/of.h> | ||
| 24 | #include <linux/of_address.h> | ||
| 25 | #include <linux/of_irq.h> | ||
| 26 | |||
| 27 | #include <linux/irqchip/arm-gic.h> | ||
| 28 | |||
| 29 | #include <asm/kvm_emulate.h> | ||
| 30 | #include <asm/kvm_arm.h> | ||
| 31 | #include <asm/kvm_mmu.h> | ||
| 32 | |||
| 33 | static struct vgic_lr vgic_v2_get_lr(const struct kvm_vcpu *vcpu, int lr) | ||
| 34 | { | ||
| 35 | struct vgic_lr lr_desc; | ||
| 36 | u32 val = vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr]; | ||
| 37 | |||
| 38 | lr_desc.irq = val & GICH_LR_VIRTUALID; | ||
| 39 | if (lr_desc.irq <= 15) | ||
| 40 | lr_desc.source = (val >> GICH_LR_PHYSID_CPUID_SHIFT) & 0x7; | ||
| 41 | else | ||
| 42 | lr_desc.source = 0; | ||
| 43 | lr_desc.state = 0; | ||
| 44 | |||
| 45 | if (val & GICH_LR_PENDING_BIT) | ||
| 46 | lr_desc.state |= LR_STATE_PENDING; | ||
| 47 | if (val & GICH_LR_ACTIVE_BIT) | ||
| 48 | lr_desc.state |= LR_STATE_ACTIVE; | ||
| 49 | if (val & GICH_LR_EOI) | ||
| 50 | lr_desc.state |= LR_EOI_INT; | ||
| 51 | |||
| 52 | return lr_desc; | ||
| 53 | } | ||
| 54 | |||
| 55 | static void vgic_v2_set_lr(struct kvm_vcpu *vcpu, int lr, | ||
| 56 | struct vgic_lr lr_desc) | ||
| 57 | { | ||
| 58 | u32 lr_val = (lr_desc.source << GICH_LR_PHYSID_CPUID_SHIFT) | lr_desc.irq; | ||
| 59 | |||
| 60 | if (lr_desc.state & LR_STATE_PENDING) | ||
| 61 | lr_val |= GICH_LR_PENDING_BIT; | ||
| 62 | if (lr_desc.state & LR_STATE_ACTIVE) | ||
| 63 | lr_val |= GICH_LR_ACTIVE_BIT; | ||
| 64 | if (lr_desc.state & LR_EOI_INT) | ||
| 65 | lr_val |= GICH_LR_EOI; | ||
| 66 | |||
| 67 | vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr] = lr_val; | ||
| 68 | } | ||
| 69 | |||
| 70 | static void vgic_v2_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr, | ||
| 71 | struct vgic_lr lr_desc) | ||
| 72 | { | ||
| 73 | if (!(lr_desc.state & LR_STATE_MASK)) | ||
| 74 | set_bit(lr, (unsigned long *)vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr); | ||
| 75 | } | ||
| 76 | |||
| 77 | static u64 vgic_v2_get_elrsr(const struct kvm_vcpu *vcpu) | ||
| 78 | { | ||
| 79 | u64 val; | ||
| 80 | |||
| 81 | #if BITS_PER_LONG == 64 | ||
| 82 | val = vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr[1]; | ||
| 83 | val <<= 32; | ||
| 84 | val |= vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr[0]; | ||
| 85 | #else | ||
| 86 | val = *(u64 *)vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr; | ||
| 87 | #endif | ||
| 88 | return val; | ||
| 89 | } | ||
| 90 | |||
| 91 | static u64 vgic_v2_get_eisr(const struct kvm_vcpu *vcpu) | ||
| 92 | { | ||
| 93 | u64 val; | ||
| 94 | |||
| 95 | #if BITS_PER_LONG == 64 | ||
| 96 | val = vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr[1]; | ||
| 97 | val <<= 32; | ||
| 98 | val |= vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr[0]; | ||
| 99 | #else | ||
| 100 | val = *(u64 *)vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr; | ||
| 101 | #endif | ||
| 102 | return val; | ||
| 103 | } | ||
| 104 | |||
| 105 | static u32 vgic_v2_get_interrupt_status(const struct kvm_vcpu *vcpu) | ||
| 106 | { | ||
| 107 | u32 misr = vcpu->arch.vgic_cpu.vgic_v2.vgic_misr; | ||
| 108 | u32 ret = 0; | ||
| 109 | |||
| 110 | if (misr & GICH_MISR_EOI) | ||
| 111 | ret |= INT_STATUS_EOI; | ||
| 112 | if (misr & GICH_MISR_U) | ||
| 113 | ret |= INT_STATUS_UNDERFLOW; | ||
| 114 | |||
| 115 | return ret; | ||
| 116 | } | ||
| 117 | |||
| 118 | static void vgic_v2_enable_underflow(struct kvm_vcpu *vcpu) | ||
| 119 | { | ||
| 120 | vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr |= GICH_HCR_UIE; | ||
| 121 | } | ||
| 122 | |||
| 123 | static void vgic_v2_disable_underflow(struct kvm_vcpu *vcpu) | ||
| 124 | { | ||
| 125 | vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr &= ~GICH_HCR_UIE; | ||
| 126 | } | ||
| 127 | |||
| 128 | static void vgic_v2_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) | ||
| 129 | { | ||
| 130 | u32 vmcr = vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr; | ||
| 131 | |||
| 132 | vmcrp->ctlr = (vmcr & GICH_VMCR_CTRL_MASK) >> GICH_VMCR_CTRL_SHIFT; | ||
| 133 | vmcrp->abpr = (vmcr & GICH_VMCR_ALIAS_BINPOINT_MASK) >> GICH_VMCR_ALIAS_BINPOINT_SHIFT; | ||
| 134 | vmcrp->bpr = (vmcr & GICH_VMCR_BINPOINT_MASK) >> GICH_VMCR_BINPOINT_SHIFT; | ||
| 135 | vmcrp->pmr = (vmcr & GICH_VMCR_PRIMASK_MASK) >> GICH_VMCR_PRIMASK_SHIFT; | ||
| 136 | } | ||
| 137 | |||
| 138 | static void vgic_v2_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) | ||
| 139 | { | ||
| 140 | u32 vmcr; | ||
| 141 | |||
| 142 | vmcr = (vmcrp->ctlr << GICH_VMCR_CTRL_SHIFT) & GICH_VMCR_CTRL_MASK; | ||
| 143 | vmcr |= (vmcrp->abpr << GICH_VMCR_ALIAS_BINPOINT_SHIFT) & GICH_VMCR_ALIAS_BINPOINT_MASK; | ||
| 144 | vmcr |= (vmcrp->bpr << GICH_VMCR_BINPOINT_SHIFT) & GICH_VMCR_BINPOINT_MASK; | ||
| 145 | vmcr |= (vmcrp->pmr << GICH_VMCR_PRIMASK_SHIFT) & GICH_VMCR_PRIMASK_MASK; | ||
| 146 | |||
| 147 | vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr = vmcr; | ||
| 148 | } | ||
| 149 | |||
| 150 | static void vgic_v2_enable(struct kvm_vcpu *vcpu) | ||
| 151 | { | ||
| 152 | /* | ||
| 153 | * By forcing VMCR to zero, the GIC will restore the binary | ||
| 154 | * points to their reset values. Anything else resets to zero | ||
| 155 | * anyway. | ||
| 156 | */ | ||
| 157 | vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr = 0; | ||
| 158 | |||
| 159 | /* Get the show on the road... */ | ||
| 160 | vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr = GICH_HCR_EN; | ||
| 161 | } | ||
| 162 | |||
| 163 | static const struct vgic_ops vgic_v2_ops = { | ||
| 164 | .get_lr = vgic_v2_get_lr, | ||
| 165 | .set_lr = vgic_v2_set_lr, | ||
| 166 | .sync_lr_elrsr = vgic_v2_sync_lr_elrsr, | ||
| 167 | .get_elrsr = vgic_v2_get_elrsr, | ||
| 168 | .get_eisr = vgic_v2_get_eisr, | ||
| 169 | .get_interrupt_status = vgic_v2_get_interrupt_status, | ||
| 170 | .enable_underflow = vgic_v2_enable_underflow, | ||
| 171 | .disable_underflow = vgic_v2_disable_underflow, | ||
| 172 | .get_vmcr = vgic_v2_get_vmcr, | ||
| 173 | .set_vmcr = vgic_v2_set_vmcr, | ||
| 174 | .enable = vgic_v2_enable, | ||
| 175 | }; | ||
| 176 | |||
| 177 | static struct vgic_params vgic_v2_params; | ||
| 178 | |||
| 179 | /** | ||
| 180 | * vgic_v2_probe - probe for a GICv2 compatible interrupt controller in DT | ||
| 181 | * @node: pointer to the DT node | ||
| 182 | * @ops: address of a pointer to the GICv2 operations | ||
| 183 | * @params: address of a pointer to HW-specific parameters | ||
| 184 | * | ||
| 185 | * Returns 0 if a GICv2 has been found, with the low level operations | ||
| 186 | * in *ops and the HW parameters in *params. Returns an error code | ||
| 187 | * otherwise. | ||
| 188 | */ | ||
| 189 | int vgic_v2_probe(struct device_node *vgic_node, | ||
| 190 | const struct vgic_ops **ops, | ||
| 191 | const struct vgic_params **params) | ||
| 192 | { | ||
| 193 | int ret; | ||
| 194 | struct resource vctrl_res; | ||
| 195 | struct resource vcpu_res; | ||
| 196 | struct vgic_params *vgic = &vgic_v2_params; | ||
| 197 | |||
| 198 | vgic->maint_irq = irq_of_parse_and_map(vgic_node, 0); | ||
| 199 | if (!vgic->maint_irq) { | ||
| 200 | kvm_err("error getting vgic maintenance irq from DT\n"); | ||
| 201 | ret = -ENXIO; | ||
| 202 | goto out; | ||
| 203 | } | ||
| 204 | |||
| 205 | ret = of_address_to_resource(vgic_node, 2, &vctrl_res); | ||
| 206 | if (ret) { | ||
| 207 | kvm_err("Cannot obtain GICH resource\n"); | ||
| 208 | goto out; | ||
| 209 | } | ||
| 210 | |||
| 211 | vgic->vctrl_base = of_iomap(vgic_node, 2); | ||
| 212 | if (!vgic->vctrl_base) { | ||
| 213 | kvm_err("Cannot ioremap GICH\n"); | ||
| 214 | ret = -ENOMEM; | ||
| 215 | goto out; | ||
| 216 | } | ||
| 217 | |||
| 218 | vgic->nr_lr = readl_relaxed(vgic->vctrl_base + GICH_VTR); | ||
| 219 | vgic->nr_lr = (vgic->nr_lr & 0x3f) + 1; | ||
| 220 | |||
| 221 | ret = create_hyp_io_mappings(vgic->vctrl_base, | ||
| 222 | vgic->vctrl_base + resource_size(&vctrl_res), | ||
| 223 | vctrl_res.start); | ||
| 224 | if (ret) { | ||
| 225 | kvm_err("Cannot map VCTRL into hyp\n"); | ||
| 226 | goto out_unmap; | ||
| 227 | } | ||
| 228 | |||
| 229 | if (of_address_to_resource(vgic_node, 3, &vcpu_res)) { | ||
| 230 | kvm_err("Cannot obtain GICV resource\n"); | ||
| 231 | ret = -ENXIO; | ||
| 232 | goto out_unmap; | ||
| 233 | } | ||
| 234 | |||
| 235 | if (!PAGE_ALIGNED(vcpu_res.start)) { | ||
| 236 | kvm_err("GICV physical address 0x%llx not page aligned\n", | ||
| 237 | (unsigned long long)vcpu_res.start); | ||
| 238 | ret = -ENXIO; | ||
| 239 | goto out_unmap; | ||
| 240 | } | ||
| 241 | |||
| 242 | if (!PAGE_ALIGNED(resource_size(&vcpu_res))) { | ||
| 243 | kvm_err("GICV size 0x%llx not a multiple of page size 0x%lx\n", | ||
| 244 | (unsigned long long)resource_size(&vcpu_res), | ||
| 245 | PAGE_SIZE); | ||
| 246 | ret = -ENXIO; | ||
| 247 | goto out_unmap; | ||
| 248 | } | ||
| 249 | |||
| 250 | vgic->vcpu_base = vcpu_res.start; | ||
| 251 | |||
| 252 | kvm_info("%s@%llx IRQ%d\n", vgic_node->name, | ||
| 253 | vctrl_res.start, vgic->maint_irq); | ||
| 254 | |||
| 255 | vgic->type = VGIC_V2; | ||
| 256 | *ops = &vgic_v2_ops; | ||
| 257 | *params = vgic; | ||
| 258 | goto out; | ||
| 259 | |||
| 260 | out_unmap: | ||
| 261 | iounmap(vgic->vctrl_base); | ||
| 262 | out: | ||
| 263 | of_node_put(vgic_node); | ||
| 264 | return ret; | ||
| 265 | } | ||
diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c new file mode 100644 index 000000000000..1c2c8eef0599 --- /dev/null +++ b/virt/kvm/arm/vgic-v3.c | |||
| @@ -0,0 +1,247 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2013 ARM Limited, All Rights Reserved. | ||
| 3 | * Author: Marc Zyngier <marc.zyngier@arm.com> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/cpu.h> | ||
| 19 | #include <linux/kvm.h> | ||
| 20 | #include <linux/kvm_host.h> | ||
| 21 | #include <linux/interrupt.h> | ||
| 22 | #include <linux/io.h> | ||
| 23 | #include <linux/of.h> | ||
| 24 | #include <linux/of_address.h> | ||
| 25 | #include <linux/of_irq.h> | ||
| 26 | |||
| 27 | #include <linux/irqchip/arm-gic-v3.h> | ||
| 28 | |||
| 29 | #include <asm/kvm_emulate.h> | ||
| 30 | #include <asm/kvm_arm.h> | ||
| 31 | #include <asm/kvm_mmu.h> | ||
| 32 | |||
| 33 | /* These are for GICv2 emulation only */ | ||
| 34 | #define GICH_LR_VIRTUALID (0x3ffUL << 0) | ||
| 35 | #define GICH_LR_PHYSID_CPUID_SHIFT (10) | ||
| 36 | #define GICH_LR_PHYSID_CPUID (7UL << GICH_LR_PHYSID_CPUID_SHIFT) | ||
| 37 | |||
| 38 | /* | ||
| 39 | * LRs are stored in reverse order in memory. make sure we index them | ||
| 40 | * correctly. | ||
| 41 | */ | ||
| 42 | #define LR_INDEX(lr) (VGIC_V3_MAX_LRS - 1 - lr) | ||
| 43 | |||
| 44 | static u32 ich_vtr_el2; | ||
| 45 | |||
| 46 | static struct vgic_lr vgic_v3_get_lr(const struct kvm_vcpu *vcpu, int lr) | ||
| 47 | { | ||
| 48 | struct vgic_lr lr_desc; | ||
| 49 | u64 val = vcpu->arch.vgic_cpu.vgic_v3.vgic_lr[LR_INDEX(lr)]; | ||
| 50 | |||
| 51 | lr_desc.irq = val & GICH_LR_VIRTUALID; | ||
| 52 | if (lr_desc.irq <= 15) | ||
| 53 | lr_desc.source = (val >> GICH_LR_PHYSID_CPUID_SHIFT) & 0x7; | ||
| 54 | else | ||
| 55 | lr_desc.source = 0; | ||
| 56 | lr_desc.state = 0; | ||
| 57 | |||
| 58 | if (val & ICH_LR_PENDING_BIT) | ||
| 59 | lr_desc.state |= LR_STATE_PENDING; | ||
| 60 | if (val & ICH_LR_ACTIVE_BIT) | ||
| 61 | lr_desc.state |= LR_STATE_ACTIVE; | ||
| 62 | if (val & ICH_LR_EOI) | ||
| 63 | lr_desc.state |= LR_EOI_INT; | ||
| 64 | |||
| 65 | return lr_desc; | ||
| 66 | } | ||
| 67 | |||
| 68 | static void vgic_v3_set_lr(struct kvm_vcpu *vcpu, int lr, | ||
| 69 | struct vgic_lr lr_desc) | ||
| 70 | { | ||
| 71 | u64 lr_val = (((u32)lr_desc.source << GICH_LR_PHYSID_CPUID_SHIFT) | | ||
| 72 | lr_desc.irq); | ||
| 73 | |||
| 74 | if (lr_desc.state & LR_STATE_PENDING) | ||
| 75 | lr_val |= ICH_LR_PENDING_BIT; | ||
| 76 | if (lr_desc.state & LR_STATE_ACTIVE) | ||
| 77 | lr_val |= ICH_LR_ACTIVE_BIT; | ||
| 78 | if (lr_desc.state & LR_EOI_INT) | ||
| 79 | lr_val |= ICH_LR_EOI; | ||
| 80 | |||
| 81 | vcpu->arch.vgic_cpu.vgic_v3.vgic_lr[LR_INDEX(lr)] = lr_val; | ||
| 82 | } | ||
| 83 | |||
| 84 | static void vgic_v3_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr, | ||
| 85 | struct vgic_lr lr_desc) | ||
| 86 | { | ||
| 87 | if (!(lr_desc.state & LR_STATE_MASK)) | ||
| 88 | vcpu->arch.vgic_cpu.vgic_v3.vgic_elrsr |= (1U << lr); | ||
| 89 | } | ||
| 90 | |||
| 91 | static u64 vgic_v3_get_elrsr(const struct kvm_vcpu *vcpu) | ||
| 92 | { | ||
| 93 | return vcpu->arch.vgic_cpu.vgic_v3.vgic_elrsr; | ||
| 94 | } | ||
| 95 | |||
| 96 | static u64 vgic_v3_get_eisr(const struct kvm_vcpu *vcpu) | ||
| 97 | { | ||
| 98 | return vcpu->arch.vgic_cpu.vgic_v3.vgic_eisr; | ||
| 99 | } | ||
| 100 | |||
| 101 | static u32 vgic_v3_get_interrupt_status(const struct kvm_vcpu *vcpu) | ||
| 102 | { | ||
| 103 | u32 misr = vcpu->arch.vgic_cpu.vgic_v3.vgic_misr; | ||
| 104 | u32 ret = 0; | ||
| 105 | |||
| 106 | if (misr & ICH_MISR_EOI) | ||
| 107 | ret |= INT_STATUS_EOI; | ||
| 108 | if (misr & ICH_MISR_U) | ||
| 109 | ret |= INT_STATUS_UNDERFLOW; | ||
| 110 | |||
| 111 | return ret; | ||
| 112 | } | ||
| 113 | |||
| 114 | static void vgic_v3_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) | ||
| 115 | { | ||
| 116 | u32 vmcr = vcpu->arch.vgic_cpu.vgic_v3.vgic_vmcr; | ||
| 117 | |||
| 118 | vmcrp->ctlr = (vmcr & ICH_VMCR_CTLR_MASK) >> ICH_VMCR_CTLR_SHIFT; | ||
| 119 | vmcrp->abpr = (vmcr & ICH_VMCR_BPR1_MASK) >> ICH_VMCR_BPR1_SHIFT; | ||
| 120 | vmcrp->bpr = (vmcr & ICH_VMCR_BPR0_MASK) >> ICH_VMCR_BPR0_SHIFT; | ||
| 121 | vmcrp->pmr = (vmcr & ICH_VMCR_PMR_MASK) >> ICH_VMCR_PMR_SHIFT; | ||
| 122 | } | ||
| 123 | |||
| 124 | static void vgic_v3_enable_underflow(struct kvm_vcpu *vcpu) | ||
| 125 | { | ||
| 126 | vcpu->arch.vgic_cpu.vgic_v3.vgic_hcr |= ICH_HCR_UIE; | ||
| 127 | } | ||
| 128 | |||
| 129 | static void vgic_v3_disable_underflow(struct kvm_vcpu *vcpu) | ||
| 130 | { | ||
| 131 | vcpu->arch.vgic_cpu.vgic_v3.vgic_hcr &= ~ICH_HCR_UIE; | ||
| 132 | } | ||
| 133 | |||
| 134 | static void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) | ||
| 135 | { | ||
| 136 | u32 vmcr; | ||
| 137 | |||
| 138 | vmcr = (vmcrp->ctlr << ICH_VMCR_CTLR_SHIFT) & ICH_VMCR_CTLR_MASK; | ||
| 139 | vmcr |= (vmcrp->abpr << ICH_VMCR_BPR1_SHIFT) & ICH_VMCR_BPR1_MASK; | ||
| 140 | vmcr |= (vmcrp->bpr << ICH_VMCR_BPR0_SHIFT) & ICH_VMCR_BPR0_MASK; | ||
| 141 | vmcr |= (vmcrp->pmr << ICH_VMCR_PMR_SHIFT) & ICH_VMCR_PMR_MASK; | ||
| 142 | |||
| 143 | vcpu->arch.vgic_cpu.vgic_v3.vgic_vmcr = vmcr; | ||
| 144 | } | ||
| 145 | |||
| 146 | static void vgic_v3_enable(struct kvm_vcpu *vcpu) | ||
| 147 | { | ||
| 148 | /* | ||
| 149 | * By forcing VMCR to zero, the GIC will restore the binary | ||
| 150 | * points to their reset values. Anything else resets to zero | ||
| 151 | * anyway. | ||
| 152 | */ | ||
| 153 | vcpu->arch.vgic_cpu.vgic_v3.vgic_vmcr = 0; | ||
| 154 | |||
| 155 | /* Get the show on the road... */ | ||
| 156 | vcpu->arch.vgic_cpu.vgic_v3.vgic_hcr = ICH_HCR_EN; | ||
| 157 | } | ||
| 158 | |||
| 159 | static const struct vgic_ops vgic_v3_ops = { | ||
| 160 | .get_lr = vgic_v3_get_lr, | ||
| 161 | .set_lr = vgic_v3_set_lr, | ||
| 162 | .sync_lr_elrsr = vgic_v3_sync_lr_elrsr, | ||
| 163 | .get_elrsr = vgic_v3_get_elrsr, | ||
| 164 | .get_eisr = vgic_v3_get_eisr, | ||
| 165 | .get_interrupt_status = vgic_v3_get_interrupt_status, | ||
| 166 | .enable_underflow = vgic_v3_enable_underflow, | ||
| 167 | .disable_underflow = vgic_v3_disable_underflow, | ||
| 168 | .get_vmcr = vgic_v3_get_vmcr, | ||
| 169 | .set_vmcr = vgic_v3_set_vmcr, | ||
| 170 | .enable = vgic_v3_enable, | ||
| 171 | }; | ||
| 172 | |||
| 173 | static struct vgic_params vgic_v3_params; | ||
| 174 | |||
| 175 | /** | ||
| 176 | * vgic_v3_probe - probe for a GICv3 compatible interrupt controller in DT | ||
| 177 | * @node: pointer to the DT node | ||
| 178 | * @ops: address of a pointer to the GICv3 operations | ||
| 179 | * @params: address of a pointer to HW-specific parameters | ||
| 180 | * | ||
| 181 | * Returns 0 if a GICv3 has been found, with the low level operations | ||
| 182 | * in *ops and the HW parameters in *params. Returns an error code | ||
| 183 | * otherwise. | ||
| 184 | */ | ||
| 185 | int vgic_v3_probe(struct device_node *vgic_node, | ||
| 186 | const struct vgic_ops **ops, | ||
| 187 | const struct vgic_params **params) | ||
| 188 | { | ||
| 189 | int ret = 0; | ||
| 190 | u32 gicv_idx; | ||
| 191 | struct resource vcpu_res; | ||
| 192 | struct vgic_params *vgic = &vgic_v3_params; | ||
| 193 | |||
| 194 | vgic->maint_irq = irq_of_parse_and_map(vgic_node, 0); | ||
| 195 | if (!vgic->maint_irq) { | ||
| 196 | kvm_err("error getting vgic maintenance irq from DT\n"); | ||
| 197 | ret = -ENXIO; | ||
| 198 | goto out; | ||
| 199 | } | ||
| 200 | |||
| 201 | ich_vtr_el2 = kvm_call_hyp(__vgic_v3_get_ich_vtr_el2); | ||
| 202 | |||
| 203 | /* | ||
| 204 | * The ListRegs field is 5 bits, but there is a architectural | ||
| 205 | * maximum of 16 list registers. Just ignore bit 4... | ||
| 206 | */ | ||
| 207 | vgic->nr_lr = (ich_vtr_el2 & 0xf) + 1; | ||
| 208 | |||
| 209 | if (of_property_read_u32(vgic_node, "#redistributor-regions", &gicv_idx)) | ||
| 210 | gicv_idx = 1; | ||
| 211 | |||
| 212 | gicv_idx += 3; /* Also skip GICD, GICC, GICH */ | ||
| 213 | if (of_address_to_resource(vgic_node, gicv_idx, &vcpu_res)) { | ||
| 214 | kvm_err("Cannot obtain GICV region\n"); | ||
| 215 | ret = -ENXIO; | ||
| 216 | goto out; | ||
| 217 | } | ||
| 218 | |||
| 219 | if (!PAGE_ALIGNED(vcpu_res.start)) { | ||
| 220 | kvm_err("GICV physical address 0x%llx not page aligned\n", | ||
| 221 | (unsigned long long)vcpu_res.start); | ||
| 222 | ret = -ENXIO; | ||
| 223 | goto out; | ||
| 224 | } | ||
| 225 | |||
| 226 | if (!PAGE_ALIGNED(resource_size(&vcpu_res))) { | ||
| 227 | kvm_err("GICV size 0x%llx not a multiple of page size 0x%lx\n", | ||
| 228 | (unsigned long long)resource_size(&vcpu_res), | ||
| 229 | PAGE_SIZE); | ||
| 230 | ret = -ENXIO; | ||
| 231 | goto out; | ||
| 232 | } | ||
| 233 | |||
| 234 | vgic->vcpu_base = vcpu_res.start; | ||
| 235 | vgic->vctrl_base = NULL; | ||
| 236 | vgic->type = VGIC_V3; | ||
| 237 | |||
| 238 | kvm_info("%s@%llx IRQ%d\n", vgic_node->name, | ||
| 239 | vcpu_res.start, vgic->maint_irq); | ||
| 240 | |||
| 241 | *ops = &vgic_v3_ops; | ||
| 242 | *params = vgic; | ||
| 243 | |||
| 244 | out: | ||
| 245 | of_node_put(vgic_node); | ||
| 246 | return ret; | ||
| 247 | } | ||
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index 476d3bf540a8..73eba793b17f 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c | |||
| @@ -76,14 +76,6 @@ | |||
| 76 | #define IMPLEMENTER_ARM 0x43b | 76 | #define IMPLEMENTER_ARM 0x43b |
| 77 | #define GICC_ARCH_VERSION_V2 0x2 | 77 | #define GICC_ARCH_VERSION_V2 0x2 |
| 78 | 78 | ||
| 79 | /* Physical address of vgic virtual cpu interface */ | ||
| 80 | static phys_addr_t vgic_vcpu_base; | ||
| 81 | |||
| 82 | /* Virtual control interface base address */ | ||
| 83 | static void __iomem *vgic_vctrl_base; | ||
| 84 | |||
| 85 | static struct device_node *vgic_node; | ||
| 86 | |||
| 87 | #define ACCESS_READ_VALUE (1 << 0) | 79 | #define ACCESS_READ_VALUE (1 << 0) |
| 88 | #define ACCESS_READ_RAZ (0 << 0) | 80 | #define ACCESS_READ_RAZ (0 << 0) |
| 89 | #define ACCESS_READ_MASK(x) ((x) & (1 << 0)) | 81 | #define ACCESS_READ_MASK(x) ((x) & (1 << 0)) |
| @@ -94,21 +86,46 @@ static struct device_node *vgic_node; | |||
| 94 | #define ACCESS_WRITE_MASK(x) ((x) & (3 << 1)) | 86 | #define ACCESS_WRITE_MASK(x) ((x) & (3 << 1)) |
| 95 | 87 | ||
| 96 | static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu); | 88 | static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu); |
| 89 | static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu); | ||
| 97 | static void vgic_update_state(struct kvm *kvm); | 90 | static void vgic_update_state(struct kvm *kvm); |
| 98 | static void vgic_kick_vcpus(struct kvm *kvm); | 91 | static void vgic_kick_vcpus(struct kvm *kvm); |
| 99 | static void vgic_dispatch_sgi(struct kvm_vcpu *vcpu, u32 reg); | 92 | static void vgic_dispatch_sgi(struct kvm_vcpu *vcpu, u32 reg); |
| 100 | static u32 vgic_nr_lr; | 93 | static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr); |
| 94 | static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc); | ||
| 95 | static void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); | ||
| 96 | static void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); | ||
| 101 | 97 | ||
| 102 | static unsigned int vgic_maint_irq; | 98 | static const struct vgic_ops *vgic_ops; |
| 99 | static const struct vgic_params *vgic; | ||
| 100 | |||
| 101 | /* | ||
| 102 | * struct vgic_bitmap contains unions that provide two views of | ||
| 103 | * the same data. In one case it is an array of registers of | ||
| 104 | * u32's, and in the other case it is a bitmap of unsigned | ||
| 105 | * longs. | ||
| 106 | * | ||
| 107 | * This does not work on 64-bit BE systems, because the bitmap access | ||
| 108 | * will store two consecutive 32-bit words with the higher-addressed | ||
| 109 | * register's bits at the lower index and the lower-addressed register's | ||
| 110 | * bits at the higher index. | ||
| 111 | * | ||
| 112 | * Therefore, swizzle the register index when accessing the 32-bit word | ||
| 113 | * registers to access the right register's value. | ||
| 114 | */ | ||
| 115 | #if defined(CONFIG_CPU_BIG_ENDIAN) && BITS_PER_LONG == 64 | ||
| 116 | #define REG_OFFSET_SWIZZLE 1 | ||
| 117 | #else | ||
| 118 | #define REG_OFFSET_SWIZZLE 0 | ||
| 119 | #endif | ||
| 103 | 120 | ||
| 104 | static u32 *vgic_bitmap_get_reg(struct vgic_bitmap *x, | 121 | static u32 *vgic_bitmap_get_reg(struct vgic_bitmap *x, |
| 105 | int cpuid, u32 offset) | 122 | int cpuid, u32 offset) |
| 106 | { | 123 | { |
| 107 | offset >>= 2; | 124 | offset >>= 2; |
| 108 | if (!offset) | 125 | if (!offset) |
| 109 | return x->percpu[cpuid].reg; | 126 | return x->percpu[cpuid].reg + (offset ^ REG_OFFSET_SWIZZLE); |
| 110 | else | 127 | else |
| 111 | return x->shared.reg + offset - 1; | 128 | return x->shared.reg + ((offset - 1) ^ REG_OFFSET_SWIZZLE); |
| 112 | } | 129 | } |
| 113 | 130 | ||
| 114 | static int vgic_bitmap_get_irq_val(struct vgic_bitmap *x, | 131 | static int vgic_bitmap_get_irq_val(struct vgic_bitmap *x, |
| @@ -241,12 +258,12 @@ static void vgic_cpu_irq_clear(struct kvm_vcpu *vcpu, int irq) | |||
| 241 | 258 | ||
| 242 | static u32 mmio_data_read(struct kvm_exit_mmio *mmio, u32 mask) | 259 | static u32 mmio_data_read(struct kvm_exit_mmio *mmio, u32 mask) |
| 243 | { | 260 | { |
| 244 | return *((u32 *)mmio->data) & mask; | 261 | return le32_to_cpu(*((u32 *)mmio->data)) & mask; |
| 245 | } | 262 | } |
| 246 | 263 | ||
| 247 | static void mmio_data_write(struct kvm_exit_mmio *mmio, u32 mask, u32 value) | 264 | static void mmio_data_write(struct kvm_exit_mmio *mmio, u32 mask, u32 value) |
| 248 | { | 265 | { |
| 249 | *((u32 *)mmio->data) = value & mask; | 266 | *((u32 *)mmio->data) = cpu_to_le32(value) & mask; |
| 250 | } | 267 | } |
| 251 | 268 | ||
| 252 | /** | 269 | /** |
| @@ -593,18 +610,6 @@ static bool handle_mmio_sgi_reg(struct kvm_vcpu *vcpu, | |||
| 593 | return false; | 610 | return false; |
| 594 | } | 611 | } |
| 595 | 612 | ||
| 596 | #define LR_CPUID(lr) \ | ||
| 597 | (((lr) & GICH_LR_PHYSID_CPUID) >> GICH_LR_PHYSID_CPUID_SHIFT) | ||
| 598 | #define LR_IRQID(lr) \ | ||
| 599 | ((lr) & GICH_LR_VIRTUALID) | ||
| 600 | |||
| 601 | static void vgic_retire_lr(int lr_nr, int irq, struct vgic_cpu *vgic_cpu) | ||
| 602 | { | ||
| 603 | clear_bit(lr_nr, vgic_cpu->lr_used); | ||
| 604 | vgic_cpu->vgic_lr[lr_nr] &= ~GICH_LR_STATE; | ||
| 605 | vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY; | ||
| 606 | } | ||
| 607 | |||
| 608 | /** | 613 | /** |
| 609 | * vgic_unqueue_irqs - move pending IRQs from LRs to the distributor | 614 | * vgic_unqueue_irqs - move pending IRQs from LRs to the distributor |
| 610 | * @vgic_cpu: Pointer to the vgic_cpu struct holding the LRs | 615 | * @vgic_cpu: Pointer to the vgic_cpu struct holding the LRs |
| @@ -622,13 +627,10 @@ static void vgic_unqueue_irqs(struct kvm_vcpu *vcpu) | |||
| 622 | struct vgic_dist *dist = &vcpu->kvm->arch.vgic; | 627 | struct vgic_dist *dist = &vcpu->kvm->arch.vgic; |
| 623 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; | 628 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; |
| 624 | int vcpu_id = vcpu->vcpu_id; | 629 | int vcpu_id = vcpu->vcpu_id; |
| 625 | int i, irq, source_cpu; | 630 | int i; |
| 626 | u32 *lr; | ||
| 627 | 631 | ||
| 628 | for_each_set_bit(i, vgic_cpu->lr_used, vgic_cpu->nr_lr) { | 632 | for_each_set_bit(i, vgic_cpu->lr_used, vgic_cpu->nr_lr) { |
| 629 | lr = &vgic_cpu->vgic_lr[i]; | 633 | struct vgic_lr lr = vgic_get_lr(vcpu, i); |
| 630 | irq = LR_IRQID(*lr); | ||
| 631 | source_cpu = LR_CPUID(*lr); | ||
| 632 | 634 | ||
| 633 | /* | 635 | /* |
| 634 | * There are three options for the state bits: | 636 | * There are three options for the state bits: |
| @@ -640,7 +642,7 @@ static void vgic_unqueue_irqs(struct kvm_vcpu *vcpu) | |||
| 640 | * If the LR holds only an active interrupt (not pending) then | 642 | * If the LR holds only an active interrupt (not pending) then |
| 641 | * just leave it alone. | 643 | * just leave it alone. |
| 642 | */ | 644 | */ |
| 643 | if ((*lr & GICH_LR_STATE) == GICH_LR_ACTIVE_BIT) | 645 | if ((lr.state & LR_STATE_MASK) == LR_STATE_ACTIVE) |
| 644 | continue; | 646 | continue; |
| 645 | 647 | ||
| 646 | /* | 648 | /* |
| @@ -649,18 +651,19 @@ static void vgic_unqueue_irqs(struct kvm_vcpu *vcpu) | |||
| 649 | * is fine, then we are only setting a few bits that were | 651 | * is fine, then we are only setting a few bits that were |
| 650 | * already set. | 652 | * already set. |
| 651 | */ | 653 | */ |
| 652 | vgic_dist_irq_set(vcpu, irq); | 654 | vgic_dist_irq_set(vcpu, lr.irq); |
| 653 | if (irq < VGIC_NR_SGIS) | 655 | if (lr.irq < VGIC_NR_SGIS) |
| 654 | dist->irq_sgi_sources[vcpu_id][irq] |= 1 << source_cpu; | 656 | dist->irq_sgi_sources[vcpu_id][lr.irq] |= 1 << lr.source; |
| 655 | *lr &= ~GICH_LR_PENDING_BIT; | 657 | lr.state &= ~LR_STATE_PENDING; |
| 658 | vgic_set_lr(vcpu, i, lr); | ||
| 656 | 659 | ||
| 657 | /* | 660 | /* |
| 658 | * If there's no state left on the LR (it could still be | 661 | * If there's no state left on the LR (it could still be |
| 659 | * active), then the LR does not hold any useful info and can | 662 | * active), then the LR does not hold any useful info and can |
| 660 | * be marked as free for other use. | 663 | * be marked as free for other use. |
| 661 | */ | 664 | */ |
| 662 | if (!(*lr & GICH_LR_STATE)) | 665 | if (!(lr.state & LR_STATE_MASK)) |
| 663 | vgic_retire_lr(i, irq, vgic_cpu); | 666 | vgic_retire_lr(i, lr.irq, vcpu); |
| 664 | 667 | ||
| 665 | /* Finally update the VGIC state. */ | 668 | /* Finally update the VGIC state. */ |
| 666 | vgic_update_state(vcpu->kvm); | 669 | vgic_update_state(vcpu->kvm); |
| @@ -989,8 +992,73 @@ static void vgic_update_state(struct kvm *kvm) | |||
| 989 | } | 992 | } |
| 990 | } | 993 | } |
| 991 | 994 | ||
| 992 | #define MK_LR_PEND(src, irq) \ | 995 | static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr) |
| 993 | (GICH_LR_PENDING_BIT | ((src) << GICH_LR_PHYSID_CPUID_SHIFT) | (irq)) | 996 | { |
| 997 | return vgic_ops->get_lr(vcpu, lr); | ||
| 998 | } | ||
| 999 | |||
| 1000 | static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, | ||
| 1001 | struct vgic_lr vlr) | ||
| 1002 | { | ||
| 1003 | vgic_ops->set_lr(vcpu, lr, vlr); | ||
| 1004 | } | ||
| 1005 | |||
| 1006 | static void vgic_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr, | ||
| 1007 | struct vgic_lr vlr) | ||
| 1008 | { | ||
| 1009 | vgic_ops->sync_lr_elrsr(vcpu, lr, vlr); | ||
| 1010 | } | ||
| 1011 | |||
| 1012 | static inline u64 vgic_get_elrsr(struct kvm_vcpu *vcpu) | ||
| 1013 | { | ||
| 1014 | return vgic_ops->get_elrsr(vcpu); | ||
| 1015 | } | ||
| 1016 | |||
| 1017 | static inline u64 vgic_get_eisr(struct kvm_vcpu *vcpu) | ||
| 1018 | { | ||
| 1019 | return vgic_ops->get_eisr(vcpu); | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | static inline u32 vgic_get_interrupt_status(struct kvm_vcpu *vcpu) | ||
| 1023 | { | ||
| 1024 | return vgic_ops->get_interrupt_status(vcpu); | ||
| 1025 | } | ||
| 1026 | |||
| 1027 | static inline void vgic_enable_underflow(struct kvm_vcpu *vcpu) | ||
| 1028 | { | ||
| 1029 | vgic_ops->enable_underflow(vcpu); | ||
| 1030 | } | ||
| 1031 | |||
| 1032 | static inline void vgic_disable_underflow(struct kvm_vcpu *vcpu) | ||
| 1033 | { | ||
| 1034 | vgic_ops->disable_underflow(vcpu); | ||
| 1035 | } | ||
| 1036 | |||
| 1037 | static inline void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr) | ||
| 1038 | { | ||
| 1039 | vgic_ops->get_vmcr(vcpu, vmcr); | ||
| 1040 | } | ||
| 1041 | |||
| 1042 | static void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr) | ||
| 1043 | { | ||
| 1044 | vgic_ops->set_vmcr(vcpu, vmcr); | ||
| 1045 | } | ||
| 1046 | |||
| 1047 | static inline void vgic_enable(struct kvm_vcpu *vcpu) | ||
| 1048 | { | ||
| 1049 | vgic_ops->enable(vcpu); | ||
| 1050 | } | ||
| 1051 | |||
| 1052 | static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu) | ||
| 1053 | { | ||
| 1054 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; | ||
| 1055 | struct vgic_lr vlr = vgic_get_lr(vcpu, lr_nr); | ||
| 1056 | |||
| 1057 | vlr.state = 0; | ||
| 1058 | vgic_set_lr(vcpu, lr_nr, vlr); | ||
| 1059 | clear_bit(lr_nr, vgic_cpu->lr_used); | ||
| 1060 | vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY; | ||
| 1061 | } | ||
| 994 | 1062 | ||
| 995 | /* | 1063 | /* |
| 996 | * An interrupt may have been disabled after being made pending on the | 1064 | * An interrupt may have been disabled after being made pending on the |
| @@ -1006,13 +1074,13 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu) | |||
| 1006 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; | 1074 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; |
| 1007 | int lr; | 1075 | int lr; |
| 1008 | 1076 | ||
| 1009 | for_each_set_bit(lr, vgic_cpu->lr_used, vgic_cpu->nr_lr) { | 1077 | for_each_set_bit(lr, vgic_cpu->lr_used, vgic->nr_lr) { |
| 1010 | int irq = vgic_cpu->vgic_lr[lr] & GICH_LR_VIRTUALID; | 1078 | struct vgic_lr vlr = vgic_get_lr(vcpu, lr); |
| 1011 | 1079 | ||
| 1012 | if (!vgic_irq_is_enabled(vcpu, irq)) { | 1080 | if (!vgic_irq_is_enabled(vcpu, vlr.irq)) { |
| 1013 | vgic_retire_lr(lr, irq, vgic_cpu); | 1081 | vgic_retire_lr(lr, vlr.irq, vcpu); |
| 1014 | if (vgic_irq_is_active(vcpu, irq)) | 1082 | if (vgic_irq_is_active(vcpu, vlr.irq)) |
| 1015 | vgic_irq_clear_active(vcpu, irq); | 1083 | vgic_irq_clear_active(vcpu, vlr.irq); |
| 1016 | } | 1084 | } |
| 1017 | } | 1085 | } |
| 1018 | } | 1086 | } |
| @@ -1024,6 +1092,7 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu) | |||
| 1024 | static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) | 1092 | static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) |
| 1025 | { | 1093 | { |
| 1026 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; | 1094 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; |
| 1095 | struct vgic_lr vlr; | ||
| 1027 | int lr; | 1096 | int lr; |
| 1028 | 1097 | ||
| 1029 | /* Sanitize the input... */ | 1098 | /* Sanitize the input... */ |
| @@ -1036,28 +1105,34 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) | |||
| 1036 | lr = vgic_cpu->vgic_irq_lr_map[irq]; | 1105 | lr = vgic_cpu->vgic_irq_lr_map[irq]; |
| 1037 | 1106 | ||
| 1038 | /* Do we have an active interrupt for the same CPUID? */ | 1107 | /* Do we have an active interrupt for the same CPUID? */ |
| 1039 | if (lr != LR_EMPTY && | 1108 | if (lr != LR_EMPTY) { |
| 1040 | (LR_CPUID(vgic_cpu->vgic_lr[lr]) == sgi_source_id)) { | 1109 | vlr = vgic_get_lr(vcpu, lr); |
| 1041 | kvm_debug("LR%d piggyback for IRQ%d %x\n", | 1110 | if (vlr.source == sgi_source_id) { |
| 1042 | lr, irq, vgic_cpu->vgic_lr[lr]); | 1111 | kvm_debug("LR%d piggyback for IRQ%d\n", lr, vlr.irq); |
| 1043 | BUG_ON(!test_bit(lr, vgic_cpu->lr_used)); | 1112 | BUG_ON(!test_bit(lr, vgic_cpu->lr_used)); |
| 1044 | vgic_cpu->vgic_lr[lr] |= GICH_LR_PENDING_BIT; | 1113 | vlr.state |= LR_STATE_PENDING; |
| 1045 | return true; | 1114 | vgic_set_lr(vcpu, lr, vlr); |
| 1115 | return true; | ||
| 1116 | } | ||
| 1046 | } | 1117 | } |
| 1047 | 1118 | ||
| 1048 | /* Try to use another LR for this interrupt */ | 1119 | /* Try to use another LR for this interrupt */ |
| 1049 | lr = find_first_zero_bit((unsigned long *)vgic_cpu->lr_used, | 1120 | lr = find_first_zero_bit((unsigned long *)vgic_cpu->lr_used, |
| 1050 | vgic_cpu->nr_lr); | 1121 | vgic->nr_lr); |
| 1051 | if (lr >= vgic_cpu->nr_lr) | 1122 | if (lr >= vgic->nr_lr) |
| 1052 | return false; | 1123 | return false; |
| 1053 | 1124 | ||
| 1054 | kvm_debug("LR%d allocated for IRQ%d %x\n", lr, irq, sgi_source_id); | 1125 | kvm_debug("LR%d allocated for IRQ%d %x\n", lr, irq, sgi_source_id); |
| 1055 | vgic_cpu->vgic_lr[lr] = MK_LR_PEND(sgi_source_id, irq); | ||
| 1056 | vgic_cpu->vgic_irq_lr_map[irq] = lr; | 1126 | vgic_cpu->vgic_irq_lr_map[irq] = lr; |
| 1057 | set_bit(lr, vgic_cpu->lr_used); | 1127 | set_bit(lr, vgic_cpu->lr_used); |
| 1058 | 1128 | ||
| 1129 | vlr.irq = irq; | ||
| 1130 | vlr.source = sgi_source_id; | ||
| 1131 | vlr.state = LR_STATE_PENDING; | ||
| 1059 | if (!vgic_irq_is_edge(vcpu, irq)) | 1132 | if (!vgic_irq_is_edge(vcpu, irq)) |
| 1060 | vgic_cpu->vgic_lr[lr] |= GICH_LR_EOI; | 1133 | vlr.state |= LR_EOI_INT; |
| 1134 | |||
| 1135 | vgic_set_lr(vcpu, lr, vlr); | ||
| 1061 | 1136 | ||
| 1062 | return true; | 1137 | return true; |
| 1063 | } | 1138 | } |
| @@ -1155,9 +1230,9 @@ static void __kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu) | |||
| 1155 | 1230 | ||
| 1156 | epilog: | 1231 | epilog: |
| 1157 | if (overflow) { | 1232 | if (overflow) { |
| 1158 | vgic_cpu->vgic_hcr |= GICH_HCR_UIE; | 1233 | vgic_enable_underflow(vcpu); |
| 1159 | } else { | 1234 | } else { |
| 1160 | vgic_cpu->vgic_hcr &= ~GICH_HCR_UIE; | 1235 | vgic_disable_underflow(vcpu); |
| 1161 | /* | 1236 | /* |
| 1162 | * We're about to run this VCPU, and we've consumed | 1237 | * We're about to run this VCPU, and we've consumed |
| 1163 | * everything the distributor had in store for | 1238 | * everything the distributor had in store for |
| @@ -1170,44 +1245,46 @@ epilog: | |||
| 1170 | 1245 | ||
| 1171 | static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) | 1246 | static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) |
| 1172 | { | 1247 | { |
| 1173 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; | 1248 | u32 status = vgic_get_interrupt_status(vcpu); |
| 1174 | bool level_pending = false; | 1249 | bool level_pending = false; |
| 1175 | 1250 | ||
| 1176 | kvm_debug("MISR = %08x\n", vgic_cpu->vgic_misr); | 1251 | kvm_debug("STATUS = %08x\n", status); |
| 1177 | 1252 | ||
| 1178 | if (vgic_cpu->vgic_misr & GICH_MISR_EOI) { | 1253 | if (status & INT_STATUS_EOI) { |
| 1179 | /* | 1254 | /* |
| 1180 | * Some level interrupts have been EOIed. Clear their | 1255 | * Some level interrupts have been EOIed. Clear their |
| 1181 | * active bit. | 1256 | * active bit. |
| 1182 | */ | 1257 | */ |
| 1183 | int lr, irq; | 1258 | u64 eisr = vgic_get_eisr(vcpu); |
| 1259 | unsigned long *eisr_ptr = (unsigned long *)&eisr; | ||
| 1260 | int lr; | ||
| 1184 | 1261 | ||
| 1185 | for_each_set_bit(lr, (unsigned long *)vgic_cpu->vgic_eisr, | 1262 | for_each_set_bit(lr, eisr_ptr, vgic->nr_lr) { |
| 1186 | vgic_cpu->nr_lr) { | 1263 | struct vgic_lr vlr = vgic_get_lr(vcpu, lr); |
| 1187 | irq = vgic_cpu->vgic_lr[lr] & GICH_LR_VIRTUALID; | ||
| 1188 | 1264 | ||
| 1189 | vgic_irq_clear_active(vcpu, irq); | 1265 | vgic_irq_clear_active(vcpu, vlr.irq); |
| 1190 | vgic_cpu->vgic_lr[lr] &= ~GICH_LR_EOI; | 1266 | WARN_ON(vlr.state & LR_STATE_MASK); |
| 1267 | vlr.state = 0; | ||
| 1268 | vgic_set_lr(vcpu, lr, vlr); | ||
| 1191 | 1269 | ||
| 1192 | /* Any additional pending interrupt? */ | 1270 | /* Any additional pending interrupt? */ |
| 1193 | if (vgic_dist_irq_is_pending(vcpu, irq)) { | 1271 | if (vgic_dist_irq_is_pending(vcpu, vlr.irq)) { |
| 1194 | vgic_cpu_irq_set(vcpu, irq); | 1272 | vgic_cpu_irq_set(vcpu, vlr.irq); |
| 1195 | level_pending = true; | 1273 | level_pending = true; |
| 1196 | } else { | 1274 | } else { |
| 1197 | vgic_cpu_irq_clear(vcpu, irq); | 1275 | vgic_cpu_irq_clear(vcpu, vlr.irq); |
| 1198 | } | 1276 | } |
| 1199 | 1277 | ||
| 1200 | /* | 1278 | /* |
| 1201 | * Despite being EOIed, the LR may not have | 1279 | * Despite being EOIed, the LR may not have |
| 1202 | * been marked as empty. | 1280 | * been marked as empty. |
| 1203 | */ | 1281 | */ |
| 1204 | set_bit(lr, (unsigned long *)vgic_cpu->vgic_elrsr); | 1282 | vgic_sync_lr_elrsr(vcpu, lr, vlr); |
| 1205 | vgic_cpu->vgic_lr[lr] &= ~GICH_LR_ACTIVE_BIT; | ||
| 1206 | } | 1283 | } |
| 1207 | } | 1284 | } |
| 1208 | 1285 | ||
| 1209 | if (vgic_cpu->vgic_misr & GICH_MISR_U) | 1286 | if (status & INT_STATUS_UNDERFLOW) |
| 1210 | vgic_cpu->vgic_hcr &= ~GICH_HCR_UIE; | 1287 | vgic_disable_underflow(vcpu); |
| 1211 | 1288 | ||
| 1212 | return level_pending; | 1289 | return level_pending; |
| 1213 | } | 1290 | } |
| @@ -1220,29 +1297,31 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) | |||
| 1220 | { | 1297 | { |
| 1221 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; | 1298 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; |
| 1222 | struct vgic_dist *dist = &vcpu->kvm->arch.vgic; | 1299 | struct vgic_dist *dist = &vcpu->kvm->arch.vgic; |
| 1300 | u64 elrsr; | ||
| 1301 | unsigned long *elrsr_ptr; | ||
| 1223 | int lr, pending; | 1302 | int lr, pending; |
| 1224 | bool level_pending; | 1303 | bool level_pending; |
| 1225 | 1304 | ||
| 1226 | level_pending = vgic_process_maintenance(vcpu); | 1305 | level_pending = vgic_process_maintenance(vcpu); |
| 1306 | elrsr = vgic_get_elrsr(vcpu); | ||
| 1307 | elrsr_ptr = (unsigned long *)&elrsr; | ||
| 1227 | 1308 | ||
| 1228 | /* Clear mappings for empty LRs */ | 1309 | /* Clear mappings for empty LRs */ |
| 1229 | for_each_set_bit(lr, (unsigned long *)vgic_cpu->vgic_elrsr, | 1310 | for_each_set_bit(lr, elrsr_ptr, vgic->nr_lr) { |
| 1230 | vgic_cpu->nr_lr) { | 1311 | struct vgic_lr vlr; |
| 1231 | int irq; | ||
| 1232 | 1312 | ||
| 1233 | if (!test_and_clear_bit(lr, vgic_cpu->lr_used)) | 1313 | if (!test_and_clear_bit(lr, vgic_cpu->lr_used)) |
| 1234 | continue; | 1314 | continue; |
| 1235 | 1315 | ||
| 1236 | irq = vgic_cpu->vgic_lr[lr] & GICH_LR_VIRTUALID; | 1316 | vlr = vgic_get_lr(vcpu, lr); |
| 1237 | 1317 | ||
| 1238 | BUG_ON(irq >= VGIC_NR_IRQS); | 1318 | BUG_ON(vlr.irq >= VGIC_NR_IRQS); |
| 1239 | vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY; | 1319 | vgic_cpu->vgic_irq_lr_map[vlr.irq] = LR_EMPTY; |
| 1240 | } | 1320 | } |
| 1241 | 1321 | ||
| 1242 | /* Check if we still have something up our sleeve... */ | 1322 | /* Check if we still have something up our sleeve... */ |
| 1243 | pending = find_first_zero_bit((unsigned long *)vgic_cpu->vgic_elrsr, | 1323 | pending = find_first_zero_bit(elrsr_ptr, vgic->nr_lr); |
| 1244 | vgic_cpu->nr_lr); | 1324 | if (level_pending || pending < vgic->nr_lr) |
| 1245 | if (level_pending || pending < vgic_cpu->nr_lr) | ||
| 1246 | set_bit(vcpu->vcpu_id, &dist->irq_pending_on_cpu); | 1325 | set_bit(vcpu->vcpu_id, &dist->irq_pending_on_cpu); |
| 1247 | } | 1326 | } |
| 1248 | 1327 | ||
| @@ -1432,21 +1511,20 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) | |||
| 1432 | } | 1511 | } |
| 1433 | 1512 | ||
| 1434 | /* | 1513 | /* |
| 1435 | * By forcing VMCR to zero, the GIC will restore the binary | 1514 | * Store the number of LRs per vcpu, so we don't have to go |
| 1436 | * points to their reset values. Anything else resets to zero | 1515 | * all the way to the distributor structure to find out. Only |
| 1437 | * anyway. | 1516 | * assembly code should use this one. |
| 1438 | */ | 1517 | */ |
| 1439 | vgic_cpu->vgic_vmcr = 0; | 1518 | vgic_cpu->nr_lr = vgic->nr_lr; |
| 1440 | 1519 | ||
| 1441 | vgic_cpu->nr_lr = vgic_nr_lr; | 1520 | vgic_enable(vcpu); |
| 1442 | vgic_cpu->vgic_hcr = GICH_HCR_EN; /* Get the show on the road... */ | ||
| 1443 | 1521 | ||
| 1444 | return 0; | 1522 | return 0; |
| 1445 | } | 1523 | } |
| 1446 | 1524 | ||
| 1447 | static void vgic_init_maintenance_interrupt(void *info) | 1525 | static void vgic_init_maintenance_interrupt(void *info) |
| 1448 | { | 1526 | { |
| 1449 | enable_percpu_irq(vgic_maint_irq, 0); | 1527 | enable_percpu_irq(vgic->maint_irq, 0); |
| 1450 | } | 1528 | } |
| 1451 | 1529 | ||
| 1452 | static int vgic_cpu_notify(struct notifier_block *self, | 1530 | static int vgic_cpu_notify(struct notifier_block *self, |
| @@ -1459,7 +1537,7 @@ static int vgic_cpu_notify(struct notifier_block *self, | |||
| 1459 | break; | 1537 | break; |
| 1460 | case CPU_DYING: | 1538 | case CPU_DYING: |
| 1461 | case CPU_DYING_FROZEN: | 1539 | case CPU_DYING_FROZEN: |
| 1462 | disable_percpu_irq(vgic_maint_irq); | 1540 | disable_percpu_irq(vgic->maint_irq); |
| 1463 | break; | 1541 | break; |
| 1464 | } | 1542 | } |
| 1465 | 1543 | ||
| @@ -1470,30 +1548,37 @@ static struct notifier_block vgic_cpu_nb = { | |||
| 1470 | .notifier_call = vgic_cpu_notify, | 1548 | .notifier_call = vgic_cpu_notify, |
| 1471 | }; | 1549 | }; |
| 1472 | 1550 | ||
| 1551 | static const struct of_device_id vgic_ids[] = { | ||
| 1552 | { .compatible = "arm,cortex-a15-gic", .data = vgic_v2_probe, }, | ||
| 1553 | { .compatible = "arm,gic-v3", .data = vgic_v3_probe, }, | ||
| 1554 | {}, | ||
| 1555 | }; | ||
| 1556 | |||
| 1473 | int kvm_vgic_hyp_init(void) | 1557 | int kvm_vgic_hyp_init(void) |
| 1474 | { | 1558 | { |
| 1559 | const struct of_device_id *matched_id; | ||
| 1560 | int (*vgic_probe)(struct device_node *,const struct vgic_ops **, | ||
| 1561 | const struct vgic_params **); | ||
| 1562 | struct device_node *vgic_node; | ||
| 1475 | int ret; | 1563 | int ret; |
| 1476 | struct resource vctrl_res; | ||
| 1477 | struct resource vcpu_res; | ||
| 1478 | 1564 | ||
| 1479 | vgic_node = of_find_compatible_node(NULL, NULL, "arm,cortex-a15-gic"); | 1565 | vgic_node = of_find_matching_node_and_match(NULL, |
| 1566 | vgic_ids, &matched_id); | ||
| 1480 | if (!vgic_node) { | 1567 | if (!vgic_node) { |
| 1481 | kvm_err("error: no compatible vgic node in DT\n"); | 1568 | kvm_err("error: no compatible GIC node found\n"); |
| 1482 | return -ENODEV; | 1569 | return -ENODEV; |
| 1483 | } | 1570 | } |
| 1484 | 1571 | ||
| 1485 | vgic_maint_irq = irq_of_parse_and_map(vgic_node, 0); | 1572 | vgic_probe = matched_id->data; |
| 1486 | if (!vgic_maint_irq) { | 1573 | ret = vgic_probe(vgic_node, &vgic_ops, &vgic); |
| 1487 | kvm_err("error getting vgic maintenance irq from DT\n"); | 1574 | if (ret) |
| 1488 | ret = -ENXIO; | 1575 | return ret; |
| 1489 | goto out; | ||
| 1490 | } | ||
| 1491 | 1576 | ||
| 1492 | ret = request_percpu_irq(vgic_maint_irq, vgic_maintenance_handler, | 1577 | ret = request_percpu_irq(vgic->maint_irq, vgic_maintenance_handler, |
| 1493 | "vgic", kvm_get_running_vcpus()); | 1578 | "vgic", kvm_get_running_vcpus()); |
| 1494 | if (ret) { | 1579 | if (ret) { |
| 1495 | kvm_err("Cannot register interrupt %d\n", vgic_maint_irq); | 1580 | kvm_err("Cannot register interrupt %d\n", vgic->maint_irq); |
| 1496 | goto out; | 1581 | return ret; |
| 1497 | } | 1582 | } |
| 1498 | 1583 | ||
| 1499 | ret = __register_cpu_notifier(&vgic_cpu_nb); | 1584 | ret = __register_cpu_notifier(&vgic_cpu_nb); |
| @@ -1502,65 +1587,15 @@ int kvm_vgic_hyp_init(void) | |||
| 1502 | goto out_free_irq; | 1587 | goto out_free_irq; |
| 1503 | } | 1588 | } |
| 1504 | 1589 | ||
| 1505 | ret = of_address_to_resource(vgic_node, 2, &vctrl_res); | 1590 | /* Callback into for arch code for setup */ |
| 1506 | if (ret) { | 1591 | vgic_arch_setup(vgic); |
| 1507 | kvm_err("Cannot obtain VCTRL resource\n"); | ||
| 1508 | goto out_free_irq; | ||
| 1509 | } | ||
| 1510 | 1592 | ||
| 1511 | vgic_vctrl_base = of_iomap(vgic_node, 2); | ||
| 1512 | if (!vgic_vctrl_base) { | ||
| 1513 | kvm_err("Cannot ioremap VCTRL\n"); | ||
| 1514 | ret = -ENOMEM; | ||
| 1515 | goto out_free_irq; | ||
| 1516 | } | ||
| 1517 | |||
| 1518 | vgic_nr_lr = readl_relaxed(vgic_vctrl_base + GICH_VTR); | ||
| 1519 | vgic_nr_lr = (vgic_nr_lr & 0x3f) + 1; | ||
| 1520 | |||
| 1521 | ret = create_hyp_io_mappings(vgic_vctrl_base, | ||
| 1522 | vgic_vctrl_base + resource_size(&vctrl_res), | ||
| 1523 | vctrl_res.start); | ||
| 1524 | if (ret) { | ||
| 1525 | kvm_err("Cannot map VCTRL into hyp\n"); | ||
| 1526 | goto out_unmap; | ||
| 1527 | } | ||
| 1528 | |||
| 1529 | if (of_address_to_resource(vgic_node, 3, &vcpu_res)) { | ||
| 1530 | kvm_err("Cannot obtain VCPU resource\n"); | ||
| 1531 | ret = -ENXIO; | ||
| 1532 | goto out_unmap; | ||
| 1533 | } | ||
| 1534 | |||
| 1535 | if (!PAGE_ALIGNED(vcpu_res.start)) { | ||
| 1536 | kvm_err("GICV physical address 0x%llx not page aligned\n", | ||
| 1537 | (unsigned long long)vcpu_res.start); | ||
| 1538 | ret = -ENXIO; | ||
| 1539 | goto out_unmap; | ||
| 1540 | } | ||
| 1541 | |||
| 1542 | if (!PAGE_ALIGNED(resource_size(&vcpu_res))) { | ||
| 1543 | kvm_err("GICV size 0x%llx not a multiple of page size 0x%lx\n", | ||
| 1544 | (unsigned long long)resource_size(&vcpu_res), | ||
| 1545 | PAGE_SIZE); | ||
| 1546 | ret = -ENXIO; | ||
| 1547 | goto out_unmap; | ||
| 1548 | } | ||
| 1549 | |||
| 1550 | vgic_vcpu_base = vcpu_res.start; | ||
| 1551 | |||
| 1552 | kvm_info("%s@%llx IRQ%d\n", vgic_node->name, | ||
| 1553 | vctrl_res.start, vgic_maint_irq); | ||
| 1554 | on_each_cpu(vgic_init_maintenance_interrupt, NULL, 1); | 1593 | on_each_cpu(vgic_init_maintenance_interrupt, NULL, 1); |
| 1555 | 1594 | ||
| 1556 | goto out; | 1595 | return 0; |
| 1557 | 1596 | ||
| 1558 | out_unmap: | ||
| 1559 | iounmap(vgic_vctrl_base); | ||
| 1560 | out_free_irq: | 1597 | out_free_irq: |
| 1561 | free_percpu_irq(vgic_maint_irq, kvm_get_running_vcpus()); | 1598 | free_percpu_irq(vgic->maint_irq, kvm_get_running_vcpus()); |
| 1562 | out: | ||
| 1563 | of_node_put(vgic_node); | ||
| 1564 | return ret; | 1599 | return ret; |
| 1565 | } | 1600 | } |
| 1566 | 1601 | ||
| @@ -1593,7 +1628,7 @@ int kvm_vgic_init(struct kvm *kvm) | |||
| 1593 | } | 1628 | } |
| 1594 | 1629 | ||
| 1595 | ret = kvm_phys_addr_ioremap(kvm, kvm->arch.vgic.vgic_cpu_base, | 1630 | ret = kvm_phys_addr_ioremap(kvm, kvm->arch.vgic.vgic_cpu_base, |
| 1596 | vgic_vcpu_base, KVM_VGIC_V2_CPU_SIZE); | 1631 | vgic->vcpu_base, KVM_VGIC_V2_CPU_SIZE); |
| 1597 | if (ret) { | 1632 | if (ret) { |
| 1598 | kvm_err("Unable to remap VGIC CPU to VCPU\n"); | 1633 | kvm_err("Unable to remap VGIC CPU to VCPU\n"); |
| 1599 | goto out; | 1634 | goto out; |
| @@ -1639,7 +1674,8 @@ int kvm_vgic_create(struct kvm *kvm) | |||
| 1639 | } | 1674 | } |
| 1640 | 1675 | ||
| 1641 | spin_lock_init(&kvm->arch.vgic.lock); | 1676 | spin_lock_init(&kvm->arch.vgic.lock); |
| 1642 | kvm->arch.vgic.vctrl_base = vgic_vctrl_base; | 1677 | kvm->arch.vgic.in_kernel = true; |
| 1678 | kvm->arch.vgic.vctrl_base = vgic->vctrl_base; | ||
| 1643 | kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF; | 1679 | kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF; |
| 1644 | kvm->arch.vgic.vgic_cpu_base = VGIC_ADDR_UNDEF; | 1680 | kvm->arch.vgic.vgic_cpu_base = VGIC_ADDR_UNDEF; |
| 1645 | 1681 | ||
| @@ -1738,39 +1774,40 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write) | |||
| 1738 | static bool handle_cpu_mmio_misc(struct kvm_vcpu *vcpu, | 1774 | static bool handle_cpu_mmio_misc(struct kvm_vcpu *vcpu, |
| 1739 | struct kvm_exit_mmio *mmio, phys_addr_t offset) | 1775 | struct kvm_exit_mmio *mmio, phys_addr_t offset) |
| 1740 | { | 1776 | { |
| 1741 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; | ||
| 1742 | u32 reg, mask = 0, shift = 0; | ||
| 1743 | bool updated = false; | 1777 | bool updated = false; |
| 1778 | struct vgic_vmcr vmcr; | ||
| 1779 | u32 *vmcr_field; | ||
| 1780 | u32 reg; | ||
| 1781 | |||
| 1782 | vgic_get_vmcr(vcpu, &vmcr); | ||
| 1744 | 1783 | ||
| 1745 | switch (offset & ~0x3) { | 1784 | switch (offset & ~0x3) { |
| 1746 | case GIC_CPU_CTRL: | 1785 | case GIC_CPU_CTRL: |
| 1747 | mask = GICH_VMCR_CTRL_MASK; | 1786 | vmcr_field = &vmcr.ctlr; |
| 1748 | shift = GICH_VMCR_CTRL_SHIFT; | ||
| 1749 | break; | 1787 | break; |
| 1750 | case GIC_CPU_PRIMASK: | 1788 | case GIC_CPU_PRIMASK: |
| 1751 | mask = GICH_VMCR_PRIMASK_MASK; | 1789 | vmcr_field = &vmcr.pmr; |
| 1752 | shift = GICH_VMCR_PRIMASK_SHIFT; | ||
| 1753 | break; | 1790 | break; |
| 1754 | case GIC_CPU_BINPOINT: | 1791 | case GIC_CPU_BINPOINT: |
| 1755 | mask = GICH_VMCR_BINPOINT_MASK; | 1792 | vmcr_field = &vmcr.bpr; |
| 1756 | shift = GICH_VMCR_BINPOINT_SHIFT; | ||
| 1757 | break; | 1793 | break; |
| 1758 | case GIC_CPU_ALIAS_BINPOINT: | 1794 | case GIC_CPU_ALIAS_BINPOINT: |
| 1759 | mask = GICH_VMCR_ALIAS_BINPOINT_MASK; | 1795 | vmcr_field = &vmcr.abpr; |
| 1760 | shift = GICH_VMCR_ALIAS_BINPOINT_SHIFT; | ||
| 1761 | break; | 1796 | break; |
| 1797 | default: | ||
| 1798 | BUG(); | ||
| 1762 | } | 1799 | } |
| 1763 | 1800 | ||
| 1764 | if (!mmio->is_write) { | 1801 | if (!mmio->is_write) { |
| 1765 | reg = (vgic_cpu->vgic_vmcr & mask) >> shift; | 1802 | reg = *vmcr_field; |
| 1766 | mmio_data_write(mmio, ~0, reg); | 1803 | mmio_data_write(mmio, ~0, reg); |
| 1767 | } else { | 1804 | } else { |
| 1768 | reg = mmio_data_read(mmio, ~0); | 1805 | reg = mmio_data_read(mmio, ~0); |
| 1769 | reg = (reg << shift) & mask; | 1806 | if (reg != *vmcr_field) { |
| 1770 | if (reg != (vgic_cpu->vgic_vmcr & mask)) | 1807 | *vmcr_field = reg; |
| 1808 | vgic_set_vmcr(vcpu, &vmcr); | ||
| 1771 | updated = true; | 1809 | updated = true; |
| 1772 | vgic_cpu->vgic_vmcr &= ~mask; | 1810 | } |
| 1773 | vgic_cpu->vgic_vmcr |= reg; | ||
| 1774 | } | 1811 | } |
| 1775 | return updated; | 1812 | return updated; |
| 1776 | } | 1813 | } |
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index 20c3af7692c5..3c5981c87c3f 100644 --- a/virt/kvm/eventfd.c +++ b/virt/kvm/eventfd.c | |||
| @@ -33,10 +33,13 @@ | |||
| 33 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
| 34 | #include <linux/srcu.h> | 34 | #include <linux/srcu.h> |
| 35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
| 36 | #include <linux/seqlock.h> | ||
| 37 | #include <trace/events/kvm.h> | ||
| 36 | 38 | ||
| 39 | #include "irq.h" | ||
| 37 | #include "iodev.h" | 40 | #include "iodev.h" |
| 38 | 41 | ||
| 39 | #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING | 42 | #ifdef CONFIG_HAVE_KVM_IRQFD |
| 40 | /* | 43 | /* |
| 41 | * -------------------------------------------------------------------- | 44 | * -------------------------------------------------------------------- |
| 42 | * irqfd: Allows an fd to be used to inject an interrupt to the guest | 45 | * irqfd: Allows an fd to be used to inject an interrupt to the guest |
| @@ -75,7 +78,8 @@ struct _irqfd { | |||
| 75 | struct kvm *kvm; | 78 | struct kvm *kvm; |
| 76 | wait_queue_t wait; | 79 | wait_queue_t wait; |
| 77 | /* Update side is protected by irqfds.lock */ | 80 | /* Update side is protected by irqfds.lock */ |
| 78 | struct kvm_kernel_irq_routing_entry __rcu *irq_entry; | 81 | struct kvm_kernel_irq_routing_entry irq_entry; |
| 82 | seqcount_t irq_entry_sc; | ||
| 79 | /* Used for level IRQ fast-path */ | 83 | /* Used for level IRQ fast-path */ |
| 80 | int gsi; | 84 | int gsi; |
| 81 | struct work_struct inject; | 85 | struct work_struct inject; |
| @@ -223,16 +227,20 @@ irqfd_wakeup(wait_queue_t *wait, unsigned mode, int sync, void *key) | |||
| 223 | { | 227 | { |
| 224 | struct _irqfd *irqfd = container_of(wait, struct _irqfd, wait); | 228 | struct _irqfd *irqfd = container_of(wait, struct _irqfd, wait); |
| 225 | unsigned long flags = (unsigned long)key; | 229 | unsigned long flags = (unsigned long)key; |
| 226 | struct kvm_kernel_irq_routing_entry *irq; | 230 | struct kvm_kernel_irq_routing_entry irq; |
| 227 | struct kvm *kvm = irqfd->kvm; | 231 | struct kvm *kvm = irqfd->kvm; |
| 232 | unsigned seq; | ||
| 228 | int idx; | 233 | int idx; |
| 229 | 234 | ||
| 230 | if (flags & POLLIN) { | 235 | if (flags & POLLIN) { |
| 231 | idx = srcu_read_lock(&kvm->irq_srcu); | 236 | idx = srcu_read_lock(&kvm->irq_srcu); |
| 232 | irq = srcu_dereference(irqfd->irq_entry, &kvm->irq_srcu); | 237 | do { |
| 238 | seq = read_seqcount_begin(&irqfd->irq_entry_sc); | ||
| 239 | irq = irqfd->irq_entry; | ||
| 240 | } while (read_seqcount_retry(&irqfd->irq_entry_sc, seq)); | ||
| 233 | /* An event has been signaled, inject an interrupt */ | 241 | /* An event has been signaled, inject an interrupt */ |
| 234 | if (irq) | 242 | if (irq.type == KVM_IRQ_ROUTING_MSI) |
| 235 | kvm_set_msi(irq, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1, | 243 | kvm_set_msi(&irq, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1, |
| 236 | false); | 244 | false); |
| 237 | else | 245 | else |
| 238 | schedule_work(&irqfd->inject); | 246 | schedule_work(&irqfd->inject); |
| @@ -272,34 +280,37 @@ irqfd_ptable_queue_proc(struct file *file, wait_queue_head_t *wqh, | |||
| 272 | } | 280 | } |
| 273 | 281 | ||
| 274 | /* Must be called under irqfds.lock */ | 282 | /* Must be called under irqfds.lock */ |
| 275 | static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd, | 283 | static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd) |
| 276 | struct kvm_irq_routing_table *irq_rt) | ||
| 277 | { | 284 | { |
| 278 | struct kvm_kernel_irq_routing_entry *e; | 285 | struct kvm_kernel_irq_routing_entry *e; |
| 286 | struct kvm_kernel_irq_routing_entry entries[KVM_NR_IRQCHIPS]; | ||
| 287 | int i, n_entries; | ||
| 279 | 288 | ||
| 280 | if (irqfd->gsi >= irq_rt->nr_rt_entries) { | 289 | n_entries = kvm_irq_map_gsi(kvm, entries, irqfd->gsi); |
| 281 | rcu_assign_pointer(irqfd->irq_entry, NULL); | 290 | |
| 282 | return; | 291 | write_seqcount_begin(&irqfd->irq_entry_sc); |
| 283 | } | 292 | |
| 293 | irqfd->irq_entry.type = 0; | ||
| 284 | 294 | ||
| 285 | hlist_for_each_entry(e, &irq_rt->map[irqfd->gsi], link) { | 295 | e = entries; |
| 296 | for (i = 0; i < n_entries; ++i, ++e) { | ||
| 286 | /* Only fast-path MSI. */ | 297 | /* Only fast-path MSI. */ |
| 287 | if (e->type == KVM_IRQ_ROUTING_MSI) | 298 | if (e->type == KVM_IRQ_ROUTING_MSI) |
| 288 | rcu_assign_pointer(irqfd->irq_entry, e); | 299 | irqfd->irq_entry = *e; |
| 289 | else | ||
| 290 | rcu_assign_pointer(irqfd->irq_entry, NULL); | ||
| 291 | } | 300 | } |
| 301 | |||
| 302 | write_seqcount_end(&irqfd->irq_entry_sc); | ||
| 292 | } | 303 | } |
| 293 | 304 | ||
| 294 | static int | 305 | static int |
| 295 | kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args) | 306 | kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args) |
| 296 | { | 307 | { |
| 297 | struct kvm_irq_routing_table *irq_rt; | ||
| 298 | struct _irqfd *irqfd, *tmp; | 308 | struct _irqfd *irqfd, *tmp; |
| 299 | struct fd f; | 309 | struct fd f; |
| 300 | struct eventfd_ctx *eventfd = NULL, *resamplefd = NULL; | 310 | struct eventfd_ctx *eventfd = NULL, *resamplefd = NULL; |
| 301 | int ret; | 311 | int ret; |
| 302 | unsigned int events; | 312 | unsigned int events; |
| 313 | int idx; | ||
| 303 | 314 | ||
| 304 | irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL); | 315 | irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL); |
| 305 | if (!irqfd) | 316 | if (!irqfd) |
| @@ -310,6 +321,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args) | |||
| 310 | INIT_LIST_HEAD(&irqfd->list); | 321 | INIT_LIST_HEAD(&irqfd->list); |
| 311 | INIT_WORK(&irqfd->inject, irqfd_inject); | 322 | INIT_WORK(&irqfd->inject, irqfd_inject); |
| 312 | INIT_WORK(&irqfd->shutdown, irqfd_shutdown); | 323 | INIT_WORK(&irqfd->shutdown, irqfd_shutdown); |
| 324 | seqcount_init(&irqfd->irq_entry_sc); | ||
| 313 | 325 | ||
| 314 | f = fdget(args->fd); | 326 | f = fdget(args->fd); |
| 315 | if (!f.file) { | 327 | if (!f.file) { |
| @@ -392,9 +404,9 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args) | |||
| 392 | goto fail; | 404 | goto fail; |
| 393 | } | 405 | } |
| 394 | 406 | ||
| 395 | irq_rt = rcu_dereference_protected(kvm->irq_routing, | 407 | idx = srcu_read_lock(&kvm->irq_srcu); |
| 396 | lockdep_is_held(&kvm->irqfds.lock)); | 408 | irqfd_update(kvm, irqfd); |
| 397 | irqfd_update(kvm, irqfd, irq_rt); | 409 | srcu_read_unlock(&kvm->irq_srcu, idx); |
| 398 | 410 | ||
| 399 | list_add_tail(&irqfd->list, &kvm->irqfds.items); | 411 | list_add_tail(&irqfd->list, &kvm->irqfds.items); |
| 400 | 412 | ||
| @@ -433,12 +445,73 @@ out: | |||
| 433 | kfree(irqfd); | 445 | kfree(irqfd); |
| 434 | return ret; | 446 | return ret; |
| 435 | } | 447 | } |
| 448 | |||
| 449 | bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin) | ||
| 450 | { | ||
| 451 | struct kvm_irq_ack_notifier *kian; | ||
| 452 | int gsi, idx; | ||
| 453 | |||
| 454 | idx = srcu_read_lock(&kvm->irq_srcu); | ||
| 455 | gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin); | ||
| 456 | if (gsi != -1) | ||
| 457 | hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list, | ||
| 458 | link) | ||
| 459 | if (kian->gsi == gsi) { | ||
| 460 | srcu_read_unlock(&kvm->irq_srcu, idx); | ||
| 461 | return true; | ||
| 462 | } | ||
| 463 | |||
| 464 | srcu_read_unlock(&kvm->irq_srcu, idx); | ||
| 465 | |||
| 466 | return false; | ||
| 467 | } | ||
| 468 | EXPORT_SYMBOL_GPL(kvm_irq_has_notifier); | ||
| 469 | |||
| 470 | void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin) | ||
| 471 | { | ||
| 472 | struct kvm_irq_ack_notifier *kian; | ||
| 473 | int gsi, idx; | ||
| 474 | |||
| 475 | trace_kvm_ack_irq(irqchip, pin); | ||
| 476 | |||
| 477 | idx = srcu_read_lock(&kvm->irq_srcu); | ||
| 478 | gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin); | ||
| 479 | if (gsi != -1) | ||
| 480 | hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list, | ||
| 481 | link) | ||
| 482 | if (kian->gsi == gsi) | ||
| 483 | kian->irq_acked(kian); | ||
| 484 | srcu_read_unlock(&kvm->irq_srcu, idx); | ||
| 485 | } | ||
| 486 | |||
| 487 | void kvm_register_irq_ack_notifier(struct kvm *kvm, | ||
| 488 | struct kvm_irq_ack_notifier *kian) | ||
| 489 | { | ||
| 490 | mutex_lock(&kvm->irq_lock); | ||
| 491 | hlist_add_head_rcu(&kian->link, &kvm->irq_ack_notifier_list); | ||
| 492 | mutex_unlock(&kvm->irq_lock); | ||
| 493 | #ifdef __KVM_HAVE_IOAPIC | ||
| 494 | kvm_vcpu_request_scan_ioapic(kvm); | ||
| 495 | #endif | ||
| 496 | } | ||
| 497 | |||
| 498 | void kvm_unregister_irq_ack_notifier(struct kvm *kvm, | ||
| 499 | struct kvm_irq_ack_notifier *kian) | ||
| 500 | { | ||
| 501 | mutex_lock(&kvm->irq_lock); | ||
| 502 | hlist_del_init_rcu(&kian->link); | ||
| 503 | mutex_unlock(&kvm->irq_lock); | ||
| 504 | synchronize_srcu(&kvm->irq_srcu); | ||
| 505 | #ifdef __KVM_HAVE_IOAPIC | ||
| 506 | kvm_vcpu_request_scan_ioapic(kvm); | ||
| 507 | #endif | ||
| 508 | } | ||
| 436 | #endif | 509 | #endif |
| 437 | 510 | ||
| 438 | void | 511 | void |
| 439 | kvm_eventfd_init(struct kvm *kvm) | 512 | kvm_eventfd_init(struct kvm *kvm) |
| 440 | { | 513 | { |
| 441 | #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING | 514 | #ifdef CONFIG_HAVE_KVM_IRQFD |
| 442 | spin_lock_init(&kvm->irqfds.lock); | 515 | spin_lock_init(&kvm->irqfds.lock); |
| 443 | INIT_LIST_HEAD(&kvm->irqfds.items); | 516 | INIT_LIST_HEAD(&kvm->irqfds.items); |
| 444 | INIT_LIST_HEAD(&kvm->irqfds.resampler_list); | 517 | INIT_LIST_HEAD(&kvm->irqfds.resampler_list); |
| @@ -447,7 +520,7 @@ kvm_eventfd_init(struct kvm *kvm) | |||
| 447 | INIT_LIST_HEAD(&kvm->ioeventfds); | 520 | INIT_LIST_HEAD(&kvm->ioeventfds); |
| 448 | } | 521 | } |
| 449 | 522 | ||
| 450 | #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING | 523 | #ifdef CONFIG_HAVE_KVM_IRQFD |
| 451 | /* | 524 | /* |
| 452 | * shutdown any irqfd's that match fd+gsi | 525 | * shutdown any irqfd's that match fd+gsi |
| 453 | */ | 526 | */ |
| @@ -466,14 +539,14 @@ kvm_irqfd_deassign(struct kvm *kvm, struct kvm_irqfd *args) | |||
| 466 | list_for_each_entry_safe(irqfd, tmp, &kvm->irqfds.items, list) { | 539 | list_for_each_entry_safe(irqfd, tmp, &kvm->irqfds.items, list) { |
| 467 | if (irqfd->eventfd == eventfd && irqfd->gsi == args->gsi) { | 540 | if (irqfd->eventfd == eventfd && irqfd->gsi == args->gsi) { |
| 468 | /* | 541 | /* |
| 469 | * This rcu_assign_pointer is needed for when | 542 | * This clearing of irq_entry.type is needed for when |
| 470 | * another thread calls kvm_irq_routing_update before | 543 | * another thread calls kvm_irq_routing_update before |
| 471 | * we flush workqueue below (we synchronize with | 544 | * we flush workqueue below (we synchronize with |
| 472 | * kvm_irq_routing_update using irqfds.lock). | 545 | * kvm_irq_routing_update using irqfds.lock). |
| 473 | * It is paired with synchronize_srcu done by caller | ||
| 474 | * of that function. | ||
| 475 | */ | 546 | */ |
| 476 | rcu_assign_pointer(irqfd->irq_entry, NULL); | 547 | write_seqcount_begin(&irqfd->irq_entry_sc); |
| 548 | irqfd->irq_entry.type = 0; | ||
| 549 | write_seqcount_end(&irqfd->irq_entry_sc); | ||
| 477 | irqfd_deactivate(irqfd); | 550 | irqfd_deactivate(irqfd); |
| 478 | } | 551 | } |
| 479 | } | 552 | } |
| @@ -528,20 +601,17 @@ kvm_irqfd_release(struct kvm *kvm) | |||
| 528 | } | 601 | } |
| 529 | 602 | ||
| 530 | /* | 603 | /* |
| 531 | * Change irq_routing and irqfd. | 604 | * Take note of a change in irq routing. |
| 532 | * Caller must invoke synchronize_srcu(&kvm->irq_srcu) afterwards. | 605 | * Caller must invoke synchronize_srcu(&kvm->irq_srcu) afterwards. |
| 533 | */ | 606 | */ |
| 534 | void kvm_irq_routing_update(struct kvm *kvm, | 607 | void kvm_irq_routing_update(struct kvm *kvm) |
| 535 | struct kvm_irq_routing_table *irq_rt) | ||
| 536 | { | 608 | { |
| 537 | struct _irqfd *irqfd; | 609 | struct _irqfd *irqfd; |
| 538 | 610 | ||
| 539 | spin_lock_irq(&kvm->irqfds.lock); | 611 | spin_lock_irq(&kvm->irqfds.lock); |
| 540 | 612 | ||
| 541 | rcu_assign_pointer(kvm->irq_routing, irq_rt); | ||
| 542 | |||
| 543 | list_for_each_entry(irqfd, &kvm->irqfds.items, list) | 613 | list_for_each_entry(irqfd, &kvm->irqfds.items, list) |
| 544 | irqfd_update(kvm, irqfd, irq_rt); | 614 | irqfd_update(kvm, irqfd); |
| 545 | 615 | ||
| 546 | spin_unlock_irq(&kvm->irqfds.lock); | 616 | spin_unlock_irq(&kvm->irqfds.lock); |
| 547 | } | 617 | } |
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index a228ee82bad2..963b8995a9e8 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c | |||
| @@ -160,9 +160,9 @@ static int kvm_set_msi_inatomic(struct kvm_kernel_irq_routing_entry *e, | |||
| 160 | */ | 160 | */ |
| 161 | int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level) | 161 | int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level) |
| 162 | { | 162 | { |
| 163 | struct kvm_kernel_irq_routing_entry entries[KVM_NR_IRQCHIPS]; | ||
| 163 | struct kvm_kernel_irq_routing_entry *e; | 164 | struct kvm_kernel_irq_routing_entry *e; |
| 164 | int ret = -EINVAL; | 165 | int ret = -EINVAL; |
| 165 | struct kvm_irq_routing_table *irq_rt; | ||
| 166 | int idx; | 166 | int idx; |
| 167 | 167 | ||
| 168 | trace_kvm_set_irq(irq, level, irq_source_id); | 168 | trace_kvm_set_irq(irq, level, irq_source_id); |
| @@ -176,15 +176,13 @@ int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level) | |||
| 176 | * which is limited to 1:1 GSI mapping. | 176 | * which is limited to 1:1 GSI mapping. |
| 177 | */ | 177 | */ |
| 178 | idx = srcu_read_lock(&kvm->irq_srcu); | 178 | idx = srcu_read_lock(&kvm->irq_srcu); |
| 179 | irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu); | 179 | if (kvm_irq_map_gsi(kvm, entries, irq) > 0) { |
| 180 | if (irq < irq_rt->nr_rt_entries) | 180 | e = &entries[0]; |
| 181 | hlist_for_each_entry(e, &irq_rt->map[irq], link) { | 181 | if (likely(e->type == KVM_IRQ_ROUTING_MSI)) |
| 182 | if (likely(e->type == KVM_IRQ_ROUTING_MSI)) | 182 | ret = kvm_set_msi_inatomic(e, kvm); |
| 183 | ret = kvm_set_msi_inatomic(e, kvm); | 183 | else |
| 184 | else | 184 | ret = -EWOULDBLOCK; |
| 185 | ret = -EWOULDBLOCK; | 185 | } |
| 186 | break; | ||
| 187 | } | ||
| 188 | srcu_read_unlock(&kvm->irq_srcu, idx); | 186 | srcu_read_unlock(&kvm->irq_srcu, idx); |
| 189 | return ret; | 187 | return ret; |
| 190 | } | 188 | } |
| @@ -264,7 +262,7 @@ void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin, | |||
| 264 | int idx, gsi; | 262 | int idx, gsi; |
| 265 | 263 | ||
| 266 | idx = srcu_read_lock(&kvm->irq_srcu); | 264 | idx = srcu_read_lock(&kvm->irq_srcu); |
| 267 | gsi = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu)->chip[irqchip][pin]; | 265 | gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin); |
| 268 | if (gsi != -1) | 266 | if (gsi != -1) |
| 269 | hlist_for_each_entry_rcu(kimn, &kvm->mask_notifier_list, link) | 267 | hlist_for_each_entry_rcu(kimn, &kvm->mask_notifier_list, link) |
| 270 | if (kimn->irq == gsi) | 268 | if (kimn->irq == gsi) |
| @@ -272,8 +270,7 @@ void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin, | |||
| 272 | srcu_read_unlock(&kvm->irq_srcu, idx); | 270 | srcu_read_unlock(&kvm->irq_srcu, idx); |
| 273 | } | 271 | } |
| 274 | 272 | ||
| 275 | int kvm_set_routing_entry(struct kvm_irq_routing_table *rt, | 273 | int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e, |
| 276 | struct kvm_kernel_irq_routing_entry *e, | ||
| 277 | const struct kvm_irq_routing_entry *ue) | 274 | const struct kvm_irq_routing_entry *ue) |
| 278 | { | 275 | { |
| 279 | int r = -EINVAL; | 276 | int r = -EINVAL; |
| @@ -304,7 +301,6 @@ int kvm_set_routing_entry(struct kvm_irq_routing_table *rt, | |||
| 304 | e->irqchip.pin = ue->u.irqchip.pin + delta; | 301 | e->irqchip.pin = ue->u.irqchip.pin + delta; |
| 305 | if (e->irqchip.pin >= max_pin) | 302 | if (e->irqchip.pin >= max_pin) |
| 306 | goto out; | 303 | goto out; |
| 307 | rt->chip[ue->u.irqchip.irqchip][e->irqchip.pin] = ue->gsi; | ||
| 308 | break; | 304 | break; |
| 309 | case KVM_IRQ_ROUTING_MSI: | 305 | case KVM_IRQ_ROUTING_MSI: |
| 310 | e->set = kvm_set_msi; | 306 | e->set = kvm_set_msi; |
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c index b43c275775cd..7f256f31df10 100644 --- a/virt/kvm/irqchip.c +++ b/virt/kvm/irqchip.c | |||
| @@ -31,65 +31,42 @@ | |||
| 31 | #include <trace/events/kvm.h> | 31 | #include <trace/events/kvm.h> |
| 32 | #include "irq.h" | 32 | #include "irq.h" |
| 33 | 33 | ||
| 34 | bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin) | 34 | struct kvm_irq_routing_table { |
| 35 | { | 35 | int chip[KVM_NR_IRQCHIPS][KVM_IRQCHIP_NUM_PINS]; |
| 36 | struct kvm_irq_ack_notifier *kian; | 36 | struct kvm_kernel_irq_routing_entry *rt_entries; |
| 37 | int gsi, idx; | 37 | u32 nr_rt_entries; |
| 38 | 38 | /* | |
| 39 | idx = srcu_read_lock(&kvm->irq_srcu); | 39 | * Array indexed by gsi. Each entry contains list of irq chips |
| 40 | gsi = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu)->chip[irqchip][pin]; | 40 | * the gsi is connected to. |
| 41 | if (gsi != -1) | 41 | */ |
| 42 | hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list, | 42 | struct hlist_head map[0]; |
| 43 | link) | 43 | }; |
| 44 | if (kian->gsi == gsi) { | ||
| 45 | srcu_read_unlock(&kvm->irq_srcu, idx); | ||
| 46 | return true; | ||
| 47 | } | ||
| 48 | |||
| 49 | srcu_read_unlock(&kvm->irq_srcu, idx); | ||
| 50 | |||
| 51 | return false; | ||
| 52 | } | ||
| 53 | EXPORT_SYMBOL_GPL(kvm_irq_has_notifier); | ||
| 54 | 44 | ||
| 55 | void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin) | 45 | int kvm_irq_map_gsi(struct kvm *kvm, |
| 46 | struct kvm_kernel_irq_routing_entry *entries, int gsi) | ||
| 56 | { | 47 | { |
| 57 | struct kvm_irq_ack_notifier *kian; | 48 | struct kvm_irq_routing_table *irq_rt; |
| 58 | int gsi, idx; | 49 | struct kvm_kernel_irq_routing_entry *e; |
| 59 | 50 | int n = 0; | |
| 60 | trace_kvm_ack_irq(irqchip, pin); | 51 | |
| 52 | irq_rt = srcu_dereference_check(kvm->irq_routing, &kvm->irq_srcu, | ||
| 53 | lockdep_is_held(&kvm->irq_lock)); | ||
| 54 | if (gsi < irq_rt->nr_rt_entries) { | ||
| 55 | hlist_for_each_entry(e, &irq_rt->map[gsi], link) { | ||
| 56 | entries[n] = *e; | ||
| 57 | ++n; | ||
| 58 | } | ||
| 59 | } | ||
| 61 | 60 | ||
| 62 | idx = srcu_read_lock(&kvm->irq_srcu); | 61 | return n; |
| 63 | gsi = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu)->chip[irqchip][pin]; | ||
| 64 | if (gsi != -1) | ||
| 65 | hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list, | ||
| 66 | link) | ||
| 67 | if (kian->gsi == gsi) | ||
| 68 | kian->irq_acked(kian); | ||
| 69 | srcu_read_unlock(&kvm->irq_srcu, idx); | ||
| 70 | } | 62 | } |
| 71 | 63 | ||
| 72 | void kvm_register_irq_ack_notifier(struct kvm *kvm, | 64 | int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin) |
| 73 | struct kvm_irq_ack_notifier *kian) | ||
| 74 | { | 65 | { |
| 75 | mutex_lock(&kvm->irq_lock); | 66 | struct kvm_irq_routing_table *irq_rt; |
| 76 | hlist_add_head_rcu(&kian->link, &kvm->irq_ack_notifier_list); | ||
| 77 | mutex_unlock(&kvm->irq_lock); | ||
| 78 | #ifdef __KVM_HAVE_IOAPIC | ||
| 79 | kvm_vcpu_request_scan_ioapic(kvm); | ||
| 80 | #endif | ||
| 81 | } | ||
| 82 | 67 | ||
| 83 | void kvm_unregister_irq_ack_notifier(struct kvm *kvm, | 68 | irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu); |
| 84 | struct kvm_irq_ack_notifier *kian) | 69 | return irq_rt->chip[irqchip][pin]; |
| 85 | { | ||
| 86 | mutex_lock(&kvm->irq_lock); | ||
| 87 | hlist_del_init_rcu(&kian->link); | ||
| 88 | mutex_unlock(&kvm->irq_lock); | ||
| 89 | synchronize_srcu(&kvm->irq_srcu); | ||
| 90 | #ifdef __KVM_HAVE_IOAPIC | ||
| 91 | kvm_vcpu_request_scan_ioapic(kvm); | ||
| 92 | #endif | ||
| 93 | } | 70 | } |
| 94 | 71 | ||
| 95 | int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi) | 72 | int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi) |
| @@ -115,9 +92,8 @@ int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi) | |||
| 115 | int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level, | 92 | int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level, |
| 116 | bool line_status) | 93 | bool line_status) |
| 117 | { | 94 | { |
| 118 | struct kvm_kernel_irq_routing_entry *e, irq_set[KVM_NR_IRQCHIPS]; | 95 | struct kvm_kernel_irq_routing_entry irq_set[KVM_NR_IRQCHIPS]; |
| 119 | int ret = -1, i = 0, idx; | 96 | int ret = -1, i, idx; |
| 120 | struct kvm_irq_routing_table *irq_rt; | ||
| 121 | 97 | ||
| 122 | trace_kvm_set_irq(irq, level, irq_source_id); | 98 | trace_kvm_set_irq(irq, level, irq_source_id); |
| 123 | 99 | ||
| @@ -126,10 +102,7 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level, | |||
| 126 | * writes to the unused one. | 102 | * writes to the unused one. |
| 127 | */ | 103 | */ |
| 128 | idx = srcu_read_lock(&kvm->irq_srcu); | 104 | idx = srcu_read_lock(&kvm->irq_srcu); |
| 129 | irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu); | 105 | i = kvm_irq_map_gsi(kvm, irq_set, irq); |
| 130 | if (irq < irq_rt->nr_rt_entries) | ||
| 131 | hlist_for_each_entry(e, &irq_rt->map[irq], link) | ||
| 132 | irq_set[i++] = *e; | ||
| 133 | srcu_read_unlock(&kvm->irq_srcu, idx); | 106 | srcu_read_unlock(&kvm->irq_srcu, idx); |
| 134 | 107 | ||
| 135 | while(i--) { | 108 | while(i--) { |
| @@ -171,9 +144,11 @@ static int setup_routing_entry(struct kvm_irq_routing_table *rt, | |||
| 171 | 144 | ||
| 172 | e->gsi = ue->gsi; | 145 | e->gsi = ue->gsi; |
| 173 | e->type = ue->type; | 146 | e->type = ue->type; |
| 174 | r = kvm_set_routing_entry(rt, e, ue); | 147 | r = kvm_set_routing_entry(e, ue); |
| 175 | if (r) | 148 | if (r) |
| 176 | goto out; | 149 | goto out; |
| 150 | if (e->type == KVM_IRQ_ROUTING_IRQCHIP) | ||
| 151 | rt->chip[e->irqchip.irqchip][e->irqchip.pin] = e->gsi; | ||
| 177 | 152 | ||
| 178 | hlist_add_head(&e->link, &rt->map[e->gsi]); | 153 | hlist_add_head(&e->link, &rt->map[e->gsi]); |
| 179 | r = 0; | 154 | r = 0; |
| @@ -224,7 +199,8 @@ int kvm_set_irq_routing(struct kvm *kvm, | |||
| 224 | 199 | ||
| 225 | mutex_lock(&kvm->irq_lock); | 200 | mutex_lock(&kvm->irq_lock); |
| 226 | old = kvm->irq_routing; | 201 | old = kvm->irq_routing; |
| 227 | kvm_irq_routing_update(kvm, new); | 202 | rcu_assign_pointer(kvm->irq_routing, new); |
| 203 | kvm_irq_routing_update(kvm); | ||
| 228 | mutex_unlock(&kvm->irq_lock); | 204 | mutex_unlock(&kvm->irq_lock); |
| 229 | 205 | ||
| 230 | synchronize_srcu_expedited(&kvm->irq_srcu); | 206 | synchronize_srcu_expedited(&kvm->irq_srcu); |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 4b6c01b477f9..33712fb26eb1 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
| @@ -465,6 +465,8 @@ static struct kvm *kvm_create_vm(unsigned long type) | |||
| 465 | 465 | ||
| 466 | #ifdef CONFIG_HAVE_KVM_IRQCHIP | 466 | #ifdef CONFIG_HAVE_KVM_IRQCHIP |
| 467 | INIT_HLIST_HEAD(&kvm->mask_notifier_list); | 467 | INIT_HLIST_HEAD(&kvm->mask_notifier_list); |
| 468 | #endif | ||
| 469 | #ifdef CONFIG_HAVE_KVM_IRQFD | ||
| 468 | INIT_HLIST_HEAD(&kvm->irq_ack_notifier_list); | 470 | INIT_HLIST_HEAD(&kvm->irq_ack_notifier_list); |
| 469 | #endif | 471 | #endif |
| 470 | 472 | ||
| @@ -2324,6 +2326,34 @@ static int kvm_ioctl_create_device(struct kvm *kvm, | |||
| 2324 | return 0; | 2326 | return 0; |
| 2325 | } | 2327 | } |
| 2326 | 2328 | ||
| 2329 | static long kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg) | ||
| 2330 | { | ||
| 2331 | switch (arg) { | ||
| 2332 | case KVM_CAP_USER_MEMORY: | ||
| 2333 | case KVM_CAP_DESTROY_MEMORY_REGION_WORKS: | ||
| 2334 | case KVM_CAP_JOIN_MEMORY_REGIONS_WORKS: | ||
| 2335 | #ifdef CONFIG_KVM_APIC_ARCHITECTURE | ||
| 2336 | case KVM_CAP_SET_BOOT_CPU_ID: | ||
| 2337 | #endif | ||
| 2338 | case KVM_CAP_INTERNAL_ERROR_DATA: | ||
| 2339 | #ifdef CONFIG_HAVE_KVM_MSI | ||
| 2340 | case KVM_CAP_SIGNAL_MSI: | ||
| 2341 | #endif | ||
| 2342 | #ifdef CONFIG_HAVE_KVM_IRQFD | ||
| 2343 | case KVM_CAP_IRQFD_RESAMPLE: | ||
| 2344 | #endif | ||
| 2345 | case KVM_CAP_CHECK_EXTENSION_VM: | ||
| 2346 | return 1; | ||
| 2347 | #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING | ||
| 2348 | case KVM_CAP_IRQ_ROUTING: | ||
| 2349 | return KVM_MAX_IRQ_ROUTES; | ||
| 2350 | #endif | ||
| 2351 | default: | ||
| 2352 | break; | ||
| 2353 | } | ||
| 2354 | return kvm_vm_ioctl_check_extension(kvm, arg); | ||
| 2355 | } | ||
| 2356 | |||
| 2327 | static long kvm_vm_ioctl(struct file *filp, | 2357 | static long kvm_vm_ioctl(struct file *filp, |
| 2328 | unsigned int ioctl, unsigned long arg) | 2358 | unsigned int ioctl, unsigned long arg) |
| 2329 | { | 2359 | { |
| @@ -2487,6 +2517,9 @@ static long kvm_vm_ioctl(struct file *filp, | |||
| 2487 | r = 0; | 2517 | r = 0; |
| 2488 | break; | 2518 | break; |
| 2489 | } | 2519 | } |
| 2520 | case KVM_CHECK_EXTENSION: | ||
| 2521 | r = kvm_vm_ioctl_check_extension_generic(kvm, arg); | ||
| 2522 | break; | ||
| 2490 | default: | 2523 | default: |
| 2491 | r = kvm_arch_vm_ioctl(filp, ioctl, arg); | 2524 | r = kvm_arch_vm_ioctl(filp, ioctl, arg); |
| 2492 | if (r == -ENOTTY) | 2525 | if (r == -ENOTTY) |
| @@ -2571,33 +2604,6 @@ static int kvm_dev_ioctl_create_vm(unsigned long type) | |||
| 2571 | return r; | 2604 | return r; |
| 2572 | } | 2605 | } |
| 2573 | 2606 | ||
| 2574 | static long kvm_dev_ioctl_check_extension_generic(long arg) | ||
| 2575 | { | ||
| 2576 | switch (arg) { | ||
| 2577 | case KVM_CAP_USER_MEMORY: | ||
| 2578 | case KVM_CAP_DESTROY_MEMORY_REGION_WORKS: | ||
| 2579 | case KVM_CAP_JOIN_MEMORY_REGIONS_WORKS: | ||
| 2580 | #ifdef CONFIG_KVM_APIC_ARCHITECTURE | ||
| 2581 | case KVM_CAP_SET_BOOT_CPU_ID: | ||
| 2582 | #endif | ||
| 2583 | case KVM_CAP_INTERNAL_ERROR_DATA: | ||
| 2584 | #ifdef CONFIG_HAVE_KVM_MSI | ||
| 2585 | case KVM_CAP_SIGNAL_MSI: | ||
| 2586 | #endif | ||
| 2587 | #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING | ||
| 2588 | case KVM_CAP_IRQFD_RESAMPLE: | ||
| 2589 | #endif | ||
| 2590 | return 1; | ||
| 2591 | #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING | ||
| 2592 | case KVM_CAP_IRQ_ROUTING: | ||
| 2593 | return KVM_MAX_IRQ_ROUTES; | ||
| 2594 | #endif | ||
| 2595 | default: | ||
| 2596 | break; | ||
| 2597 | } | ||
| 2598 | return kvm_dev_ioctl_check_extension(arg); | ||
| 2599 | } | ||
| 2600 | |||
| 2601 | static long kvm_dev_ioctl(struct file *filp, | 2607 | static long kvm_dev_ioctl(struct file *filp, |
| 2602 | unsigned int ioctl, unsigned long arg) | 2608 | unsigned int ioctl, unsigned long arg) |
| 2603 | { | 2609 | { |
| @@ -2614,7 +2620,7 @@ static long kvm_dev_ioctl(struct file *filp, | |||
| 2614 | r = kvm_dev_ioctl_create_vm(arg); | 2620 | r = kvm_dev_ioctl_create_vm(arg); |
| 2615 | break; | 2621 | break; |
| 2616 | case KVM_CHECK_EXTENSION: | 2622 | case KVM_CHECK_EXTENSION: |
| 2617 | r = kvm_dev_ioctl_check_extension_generic(arg); | 2623 | r = kvm_vm_ioctl_check_extension_generic(NULL, arg); |
| 2618 | break; | 2624 | break; |
| 2619 | case KVM_GET_VCPU_MMAP_SIZE: | 2625 | case KVM_GET_VCPU_MMAP_SIZE: |
| 2620 | r = -EINVAL; | 2626 | r = -EINVAL; |
