[PATCH v6 1/1] KVM: PPC: Book3S: Add MMIO emulation for VMX instructions

2018-02-03 Thread Jose Ricardo Ziviani
This patch provides the MMIO load/store vector indexed
X-Form emulation.

Instructions implemented:
lvx: the quadword in storage addressed by the result of EA &
0x___fff0 is loaded into VRT.

stvx: the contents of VRS are stored into the quadword in storage
addressed by the result of EA & 0x___fff0.

Reported-by: Gopesh Kumar Chaudhary <gopch...@in.ibm.com>
Reported-by: Balamuruhan S <bal...@linux.vnet.ibm.com>
Signed-off-by: Paul Mackerras <pau...@ozlabs.org>
Signed-off-by: Jose Ricardo Ziviani <jos...@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/kvm_host.h   |   2 +
 arch/powerpc/include/asm/kvm_ppc.h|   4 +
 arch/powerpc/include/asm/ppc-opcode.h |   6 ++
 arch/powerpc/kvm/emulate_loadstore.c  |  34 
 arch/powerpc/kvm/powerpc.c| 150 ++
 5 files changed, 196 insertions(+)

diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index 3aa5b577cd60..045acc843e98 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -690,6 +690,7 @@ struct kvm_vcpu_arch {
u8 mmio_vsx_offset;
u8 mmio_vsx_copy_type;
u8 mmio_vsx_tx_sx_enabled;
+   u8 mmio_vmx_copy_nums;
u8 osi_needed;
u8 osi_enabled;
u8 papr_enabled;
@@ -800,6 +801,7 @@ struct kvm_vcpu_arch {
 #define KVM_MMIO_REG_QPR   0x0040
 #define KVM_MMIO_REG_FQPR  0x0060
 #define KVM_MMIO_REG_VSX   0x0080
+#define KVM_MMIO_REG_VMX   0x00c0
 
 #define __KVM_HAVE_ARCH_WQP
 #define __KVM_HAVE_CREATE_DEVICE
diff --git a/arch/powerpc/include/asm/kvm_ppc.h 
b/arch/powerpc/include/asm/kvm_ppc.h
index 9db18287b5f4..7765a800ddae 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -81,6 +81,10 @@ extern int kvmppc_handle_loads(struct kvm_run *run, struct 
kvm_vcpu *vcpu,
 extern int kvmppc_handle_vsx_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
unsigned int rt, unsigned int bytes,
int is_default_endian, int mmio_sign_extend);
+extern int kvmppc_handle_load128_by2x64(struct kvm_run *run,
+   struct kvm_vcpu *vcpu, unsigned int rt, int is_default_endian);
+extern int kvmppc_handle_store128_by2x64(struct kvm_run *run,
+   struct kvm_vcpu *vcpu, unsigned int rs, int is_default_endian);
 extern int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
   u64 val, unsigned int bytes,
   int is_default_endian);
diff --git a/arch/powerpc/include/asm/ppc-opcode.h 
b/arch/powerpc/include/asm/ppc-opcode.h
index ab5c1588b487..f1083bcf449c 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -156,6 +156,12 @@
 #define OP_31_XOP_LFDX  599
 #define OP_31_XOP_LFDUX631
 
+/* VMX Vector Load Instructions */
+#define OP_31_XOP_LVX   103
+
+/* VMX Vector Store Instructions */
+#define OP_31_XOP_STVX  231
+
 #define OP_LWZ  32
 #define OP_STFS 52
 #define OP_STFSU 53
diff --git a/arch/powerpc/kvm/emulate_loadstore.c 
b/arch/powerpc/kvm/emulate_loadstore.c
index af833531af31..332b82eafd48 100644
--- a/arch/powerpc/kvm/emulate_loadstore.c
+++ b/arch/powerpc/kvm/emulate_loadstore.c
@@ -58,6 +58,18 @@ static bool kvmppc_check_vsx_disabled(struct kvm_vcpu *vcpu)
 }
 #endif /* CONFIG_VSX */
 
+#ifdef CONFIG_ALTIVEC
+static bool kvmppc_check_altivec_disabled(struct kvm_vcpu *vcpu)
+{
+   if (!(kvmppc_get_msr(vcpu) & MSR_VEC)) {
+   kvmppc_core_queue_vec_unavail(vcpu);
+   return true;
+   }
+
+   return false;
+}
+#endif /* CONFIG_ALTIVEC */
+
 /*
  * XXX to do:
  * lfiwax, lfiwzx
@@ -98,6 +110,7 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
vcpu->arch.mmio_vsx_copy_type = KVMPPC_VSX_COPY_NONE;
vcpu->arch.mmio_sp64_extend = 0;
vcpu->arch.mmio_sign_extend = 0;
+   vcpu->arch.mmio_vmx_copy_nums = 0;
 
switch (get_op(inst)) {
case 31:
@@ -459,6 +472,27 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
 rs, 4, 1);
break;
 #endif /* CONFIG_VSX */
+
+#ifdef CONFIG_ALTIVEC
+   case OP_31_XOP_LVX:
+   if (kvmppc_check_altivec_disabled(vcpu))
+   return EMULATE_DONE;
+   vcpu->arch.vaddr_accessed &= ~0xFULL;
+   vcpu->arch.mmio_vmx_copy_nums = 2;
+   emulated = kvmppc_handle_load128_by2x64(run, vcpu,
+   KVM_MMIO_REG_VMX|rt, 1);
+   break;
+
+   case OP_31_XOP_STVX:
+   if (kvmppc_check_altivec_disabled(vcpu))
+   return EMULATE_DONE;
+   vcpu->

[PATCH v6 0/1] Implements MMIO emulation for lvx/stvx instructions

2018-02-03 Thread Jose Ricardo Ziviani
v6:
  - Applied Paul's code suggestion to fix endianess
  - Moved kvmppc_get_vsr_dword_offset() back to #ifdef CONFIG_VSX

v5:
  - Fixed the mask off of the effective address

v4:
  - Changed KVM_MMIO_REG_VMX to 0xc0 because there are 64 VSX registers

v3:
  - Added Reported-by in the commit message

v2:
  - kvmppc_get_vsr_word_offset() moved back to its original place
  - EA AND ~0xF, following ISA.
  - fixed BE/LE cases

TESTS:

For testing purposes I wrote a small program that performs stvx/lvx using the
program's virtual memory and using MMIO. Load/Store into virtual memory is the
model I use to check if MMIO results are correct (because only MMIO is emulated
by KVM).

Results:

HOST LE - GUEST BE
address: 0x10034850010
0x2143658778563412
io_address: 0x3fff89a2
0x2143658778563412

HOST LE - GUEST LE
address: 0x10033a20010
0x1234567887654321
io_address: 0x3fffb538
0x1234567887654321

HOST BE - GUEST BE
address: 0x1002c4a0010
0x2143658778563412
io_address: 0x3ffface4
0x2143658778563412

HOST BR - GUEST LE
address: 0x100225e0010
0x1234567887654321
io_address: 0x3fff7fcb
0x1234567887654321

This patch implements MMIO emulation for two instructions: lvx and stvx.

Jose Ricardo Ziviani (1):
  KVM: PPC: Book3S: Add MMIO emulation for VMX instructions

 arch/powerpc/include/asm/kvm_host.h   |   2 +
 arch/powerpc/include/asm/kvm_ppc.h|   4 +
 arch/powerpc/include/asm/ppc-opcode.h |   6 ++
 arch/powerpc/kvm/emulate_loadstore.c  |  34 
 arch/powerpc/kvm/powerpc.c| 150 ++
 5 files changed, 196 insertions(+)

-- 
2.14.3



[PATCH v5 1/1] KVM: PPC: Book3S: Add MMIO emulation for VMX instructions

2018-02-01 Thread Jose Ricardo Ziviani
This patch provides the MMIO load/store vector indexed
X-Form emulation.

Instructions implemented:
lvx: the quadword in storage addressed by the result of EA &
0x___fff0 is loaded into VRT.

stvx: the contents of VRS are stored into the quadword in storage
addressed by the result of EA & 0x___fff0.

Reported-by: Gopesh Kumar Chaudhary <gopch...@in.ibm.com>
Reported-by: Balamuruhan S <bal...@linux.vnet.ibm.com>
Signed-off-by: Jose Ricardo Ziviani <jos...@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/kvm_host.h   |   2 +
 arch/powerpc/include/asm/kvm_ppc.h|   4 +
 arch/powerpc/include/asm/ppc-opcode.h |   6 ++
 arch/powerpc/kvm/emulate_loadstore.c  |  34 
 arch/powerpc/kvm/powerpc.c| 153 +-
 5 files changed, 198 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index 3aa5b577cd60..045acc843e98 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -690,6 +690,7 @@ struct kvm_vcpu_arch {
u8 mmio_vsx_offset;
u8 mmio_vsx_copy_type;
u8 mmio_vsx_tx_sx_enabled;
+   u8 mmio_vmx_copy_nums;
u8 osi_needed;
u8 osi_enabled;
u8 papr_enabled;
@@ -800,6 +801,7 @@ struct kvm_vcpu_arch {
 #define KVM_MMIO_REG_QPR   0x0040
 #define KVM_MMIO_REG_FQPR  0x0060
 #define KVM_MMIO_REG_VSX   0x0080
+#define KVM_MMIO_REG_VMX   0x00c0
 
 #define __KVM_HAVE_ARCH_WQP
 #define __KVM_HAVE_CREATE_DEVICE
diff --git a/arch/powerpc/include/asm/kvm_ppc.h 
b/arch/powerpc/include/asm/kvm_ppc.h
index 9db18287b5f4..7765a800ddae 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -81,6 +81,10 @@ extern int kvmppc_handle_loads(struct kvm_run *run, struct 
kvm_vcpu *vcpu,
 extern int kvmppc_handle_vsx_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
unsigned int rt, unsigned int bytes,
int is_default_endian, int mmio_sign_extend);
+extern int kvmppc_handle_load128_by2x64(struct kvm_run *run,
+   struct kvm_vcpu *vcpu, unsigned int rt, int is_default_endian);
+extern int kvmppc_handle_store128_by2x64(struct kvm_run *run,
+   struct kvm_vcpu *vcpu, unsigned int rs, int is_default_endian);
 extern int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
   u64 val, unsigned int bytes,
   int is_default_endian);
diff --git a/arch/powerpc/include/asm/ppc-opcode.h 
b/arch/powerpc/include/asm/ppc-opcode.h
index ab5c1588b487..f1083bcf449c 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -156,6 +156,12 @@
 #define OP_31_XOP_LFDX  599
 #define OP_31_XOP_LFDUX631
 
+/* VMX Vector Load Instructions */
+#define OP_31_XOP_LVX   103
+
+/* VMX Vector Store Instructions */
+#define OP_31_XOP_STVX  231
+
 #define OP_LWZ  32
 #define OP_STFS 52
 #define OP_STFSU 53
diff --git a/arch/powerpc/kvm/emulate_loadstore.c 
b/arch/powerpc/kvm/emulate_loadstore.c
index af833531af31..332b82eafd48 100644
--- a/arch/powerpc/kvm/emulate_loadstore.c
+++ b/arch/powerpc/kvm/emulate_loadstore.c
@@ -58,6 +58,18 @@ static bool kvmppc_check_vsx_disabled(struct kvm_vcpu *vcpu)
 }
 #endif /* CONFIG_VSX */
 
+#ifdef CONFIG_ALTIVEC
+static bool kvmppc_check_altivec_disabled(struct kvm_vcpu *vcpu)
+{
+   if (!(kvmppc_get_msr(vcpu) & MSR_VEC)) {
+   kvmppc_core_queue_vec_unavail(vcpu);
+   return true;
+   }
+
+   return false;
+}
+#endif /* CONFIG_ALTIVEC */
+
 /*
  * XXX to do:
  * lfiwax, lfiwzx
@@ -98,6 +110,7 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
vcpu->arch.mmio_vsx_copy_type = KVMPPC_VSX_COPY_NONE;
vcpu->arch.mmio_sp64_extend = 0;
vcpu->arch.mmio_sign_extend = 0;
+   vcpu->arch.mmio_vmx_copy_nums = 0;
 
switch (get_op(inst)) {
case 31:
@@ -459,6 +472,27 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
 rs, 4, 1);
break;
 #endif /* CONFIG_VSX */
+
+#ifdef CONFIG_ALTIVEC
+   case OP_31_XOP_LVX:
+   if (kvmppc_check_altivec_disabled(vcpu))
+   return EMULATE_DONE;
+   vcpu->arch.vaddr_accessed &= ~0xFULL;
+   vcpu->arch.mmio_vmx_copy_nums = 2;
+   emulated = kvmppc_handle_load128_by2x64(run, vcpu,
+   KVM_MMIO_REG_VMX|rt, 1);
+   break;
+
+   case OP_31_XOP_STVX:
+   if (kvmppc_check_altivec_disabled(vcpu))
+   return EMULATE_DONE;
+   vcpu->arch.vaddr_accessed &= ~0xFULL

[PATCH v5 0/1] Implements MMIO emulation for lvx/stvx instructions

2018-02-01 Thread Jose Ricardo Ziviani
v5:
 - Fixed the mask off of the effective address

v4:
  - Changed KVM_MMIO_REG_VMX to 0xc0 because there are 64 VSX registers

v3:
  - Added Reported-by in the commit message

v2:
  - kvmppc_get_vsr_word_offset() moved back to its original place
  - EA AND ~0xF, following ISA.
  - fixed BE/LE cases

TESTS:

For testing purposes I wrote a small program that performs stvx/lvx using the
program's virtual memory and using MMIO. Load/Store into virtual memory is the
model I use to check if MMIO results are correct (because only MMIO is emulated
by KVM).

Results:

HOST LE - GUEST BE
address: 0x10034850010
0x2143658778563412
io_address: 0x3fff89a2
0x2143658778563412

HOST LE - GUEST LE
address: 0x10033a20010
0x1234567887654321
io_address: 0x3fffb538
0x1234567887654321

HOST BE - GUEST BE
address: 0x1002c4a0010
0x2143658778563412
io_address: 0x3ffface4
0x2143658778563412

HOST BR - GUEST LE
address: 0x100225e0010
0x1234567887654321
io_address: 0x3fff7fcb
0x1234567887654321

This patch implements MMIO emulation for two instructions: lvx and stvx.

Jose Ricardo Ziviani (1):
  KVM: PPC: Book3S: Add MMIO emulation for VMX instructions

 arch/powerpc/include/asm/kvm_host.h   |   2 +
 arch/powerpc/include/asm/kvm_ppc.h|   4 +
 arch/powerpc/include/asm/ppc-opcode.h |   6 ++
 arch/powerpc/kvm/emulate_loadstore.c  |  34 
 arch/powerpc/kvm/powerpc.c| 153 +-
 5 files changed, 198 insertions(+), 1 deletion(-)

-- 
2.14.3



[PATCH v4 1/1] KVM: PPC: Book3S: Add MMIO emulation for VMX instructions

2018-02-01 Thread Jose Ricardo Ziviani
This patch provides the MMIO load/store vector indexed
X-Form emulation.

Instructions implemented:
lvx: the quadword in storage addressed by the result of EA &
0x___fff0 is loaded into VRT.

stvx: the contents of VRS are stored into the quadword in storage
addressed by the result of EA & 0x___fff0.

Reported-by: Gopesh Kumar Chaudhary <gopch...@in.ibm.com>
Reported-by: Balamuruhan S <bal...@linux.vnet.ibm.com>
Signed-off-by: Jose Ricardo Ziviani <jos...@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/kvm_host.h   |   2 +
 arch/powerpc/include/asm/kvm_ppc.h|   4 +
 arch/powerpc/include/asm/ppc-opcode.h |   6 ++
 arch/powerpc/kvm/emulate_loadstore.c  |  34 
 arch/powerpc/kvm/powerpc.c| 153 +-
 5 files changed, 198 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index 3aa5b577cd60..045acc843e98 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -690,6 +690,7 @@ struct kvm_vcpu_arch {
u8 mmio_vsx_offset;
u8 mmio_vsx_copy_type;
u8 mmio_vsx_tx_sx_enabled;
+   u8 mmio_vmx_copy_nums;
u8 osi_needed;
u8 osi_enabled;
u8 papr_enabled;
@@ -800,6 +801,7 @@ struct kvm_vcpu_arch {
 #define KVM_MMIO_REG_QPR   0x0040
 #define KVM_MMIO_REG_FQPR  0x0060
 #define KVM_MMIO_REG_VSX   0x0080
+#define KVM_MMIO_REG_VMX   0x00c0
 
 #define __KVM_HAVE_ARCH_WQP
 #define __KVM_HAVE_CREATE_DEVICE
diff --git a/arch/powerpc/include/asm/kvm_ppc.h 
b/arch/powerpc/include/asm/kvm_ppc.h
index 9db18287b5f4..7765a800ddae 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -81,6 +81,10 @@ extern int kvmppc_handle_loads(struct kvm_run *run, struct 
kvm_vcpu *vcpu,
 extern int kvmppc_handle_vsx_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
unsigned int rt, unsigned int bytes,
int is_default_endian, int mmio_sign_extend);
+extern int kvmppc_handle_load128_by2x64(struct kvm_run *run,
+   struct kvm_vcpu *vcpu, unsigned int rt, int is_default_endian);
+extern int kvmppc_handle_store128_by2x64(struct kvm_run *run,
+   struct kvm_vcpu *vcpu, unsigned int rs, int is_default_endian);
 extern int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
   u64 val, unsigned int bytes,
   int is_default_endian);
diff --git a/arch/powerpc/include/asm/ppc-opcode.h 
b/arch/powerpc/include/asm/ppc-opcode.h
index ab5c1588b487..f1083bcf449c 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -156,6 +156,12 @@
 #define OP_31_XOP_LFDX  599
 #define OP_31_XOP_LFDUX631
 
+/* VMX Vector Load Instructions */
+#define OP_31_XOP_LVX   103
+
+/* VMX Vector Store Instructions */
+#define OP_31_XOP_STVX  231
+
 #define OP_LWZ  32
 #define OP_STFS 52
 #define OP_STFSU 53
diff --git a/arch/powerpc/kvm/emulate_loadstore.c 
b/arch/powerpc/kvm/emulate_loadstore.c
index af833531af31..7c92b6867f3e 100644
--- a/arch/powerpc/kvm/emulate_loadstore.c
+++ b/arch/powerpc/kvm/emulate_loadstore.c
@@ -58,6 +58,18 @@ static bool kvmppc_check_vsx_disabled(struct kvm_vcpu *vcpu)
 }
 #endif /* CONFIG_VSX */
 
+#ifdef CONFIG_ALTIVEC
+static bool kvmppc_check_altivec_disabled(struct kvm_vcpu *vcpu)
+{
+   if (!(kvmppc_get_msr(vcpu) & MSR_VEC)) {
+   kvmppc_core_queue_vec_unavail(vcpu);
+   return true;
+   }
+
+   return false;
+}
+#endif /* CONFIG_ALTIVEC */
+
 /*
  * XXX to do:
  * lfiwax, lfiwzx
@@ -98,6 +110,7 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
vcpu->arch.mmio_vsx_copy_type = KVMPPC_VSX_COPY_NONE;
vcpu->arch.mmio_sp64_extend = 0;
vcpu->arch.mmio_sign_extend = 0;
+   vcpu->arch.mmio_vmx_copy_nums = 0;
 
switch (get_op(inst)) {
case 31:
@@ -459,6 +472,27 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
 rs, 4, 1);
break;
 #endif /* CONFIG_VSX */
+
+#ifdef CONFIG_ALTIVEC
+   case OP_31_XOP_LVX:
+   if (kvmppc_check_altivec_disabled(vcpu))
+   return EMULATE_DONE;
+   vcpu->arch.vaddr_accessed = ~0xFULL;
+   vcpu->arch.mmio_vmx_copy_nums = 2;
+   emulated = kvmppc_handle_load128_by2x64(run, vcpu,
+   KVM_MMIO_REG_VMX|rt, 1);
+   break;
+
+   case OP_31_XOP_STVX:
+   if (kvmppc_check_altivec_disabled(vcpu))
+   return EMULATE_DONE;
+   vcpu->arch.vaddr_accessed = ~0xFULL;
+ 

[PATCH v4 0/1] Implements MMIO emulation for lvx/stvx instructions

2018-02-01 Thread Jose Ricardo Ziviani
v4:
  - Changed KVM_MMIO_REG_VMX to 0xc0 because there are 64 VSX registers

v3:
  - Added Reported-by in the commit message

v2:
  - kvmppc_get_vsr_word_offset() moved back to its original place
  - EA AND ~0xF, following ISA.
  - fixed BE/LE cases

TESTS:

For testing purposes I wrote a small program that performs stvx/lvx using the
program's virtual memory and using MMIO. Load/Store into virtual memory is the
model I use to check if MMIO results are correct (because only MMIO is emulated
by KVM).

Results:

HOST LE - GUEST BE
address: 0x10034850010
0x2143658778563412
io_address: 0x3fff89a2
0x2143658778563412

HOST LE - GUEST LE
address: 0x10033a20010
0x1234567887654321
io_address: 0x3fffb538
0x1234567887654321

HOST BE - GUEST BE
address: 0x1002c4a0010
0x2143658778563412
io_address: 0x3ffface4
0x2143658778563412

HOST BR - GUEST LE
address: 0x100225e0010
0x1234567887654321
io_address: 0x3fff7fcb
0x1234567887654321

This patch implements MMIO emulation for two instructions: lvx and stvx.

Jose Ricardo Ziviani (1):
  KVM: PPC: Book3S: Add MMIO emulation for VMX instructions

 arch/powerpc/include/asm/kvm_host.h   |   2 +
 arch/powerpc/include/asm/kvm_ppc.h|   4 +
 arch/powerpc/include/asm/ppc-opcode.h |   6 ++
 arch/powerpc/kvm/emulate_loadstore.c  |  34 
 arch/powerpc/kvm/powerpc.c| 153 +-
 5 files changed, 198 insertions(+), 1 deletion(-)

-- 
2.14.3



[PATCH v3 1/1] KVM: PPC: Book3S: Add MMIO emulation for VMX instructions

2018-01-31 Thread Jose Ricardo Ziviani
This patch provides the MMIO load/store vector indexed
X-Form emulation.

Instructions implemented:
lvx: the quadword in storage addressed by the result of EA &
0x___fff0 is loaded into VRT.

stvx: the contents of VRS are stored into the quadword in storage
addressed by the result of EA & 0x___fff0.

Reported-by: Gopesh Kumar Chaudhary <gopch...@in.ibm.com>
Reported-by: Balamuruhan S <bal...@linux.vnet.ibm.com>
Signed-off-by: Jose Ricardo Ziviani <jos...@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/kvm_host.h   |   2 +
 arch/powerpc/include/asm/kvm_ppc.h|   4 +
 arch/powerpc/include/asm/ppc-opcode.h |   6 ++
 arch/powerpc/kvm/emulate_loadstore.c  |  34 
 arch/powerpc/kvm/powerpc.c| 153 +-
 5 files changed, 198 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index 3aa5b577cd60..2c14a78c61a4 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -690,6 +690,7 @@ struct kvm_vcpu_arch {
u8 mmio_vsx_offset;
u8 mmio_vsx_copy_type;
u8 mmio_vsx_tx_sx_enabled;
+   u8 mmio_vmx_copy_nums;
u8 osi_needed;
u8 osi_enabled;
u8 papr_enabled;
@@ -800,6 +801,7 @@ struct kvm_vcpu_arch {
 #define KVM_MMIO_REG_QPR   0x0040
 #define KVM_MMIO_REG_FQPR  0x0060
 #define KVM_MMIO_REG_VSX   0x0080
+#define KVM_MMIO_REG_VMX   0x00a0
 
 #define __KVM_HAVE_ARCH_WQP
 #define __KVM_HAVE_CREATE_DEVICE
diff --git a/arch/powerpc/include/asm/kvm_ppc.h 
b/arch/powerpc/include/asm/kvm_ppc.h
index 9db18287b5f4..7765a800ddae 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -81,6 +81,10 @@ extern int kvmppc_handle_loads(struct kvm_run *run, struct 
kvm_vcpu *vcpu,
 extern int kvmppc_handle_vsx_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
unsigned int rt, unsigned int bytes,
int is_default_endian, int mmio_sign_extend);
+extern int kvmppc_handle_load128_by2x64(struct kvm_run *run,
+   struct kvm_vcpu *vcpu, unsigned int rt, int is_default_endian);
+extern int kvmppc_handle_store128_by2x64(struct kvm_run *run,
+   struct kvm_vcpu *vcpu, unsigned int rs, int is_default_endian);
 extern int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
   u64 val, unsigned int bytes,
   int is_default_endian);
diff --git a/arch/powerpc/include/asm/ppc-opcode.h 
b/arch/powerpc/include/asm/ppc-opcode.h
index ab5c1588b487..f1083bcf449c 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -156,6 +156,12 @@
 #define OP_31_XOP_LFDX  599
 #define OP_31_XOP_LFDUX631
 
+/* VMX Vector Load Instructions */
+#define OP_31_XOP_LVX   103
+
+/* VMX Vector Store Instructions */
+#define OP_31_XOP_STVX  231
+
 #define OP_LWZ  32
 #define OP_STFS 52
 #define OP_STFSU 53
diff --git a/arch/powerpc/kvm/emulate_loadstore.c 
b/arch/powerpc/kvm/emulate_loadstore.c
index af833531af31..7c92b6867f3e 100644
--- a/arch/powerpc/kvm/emulate_loadstore.c
+++ b/arch/powerpc/kvm/emulate_loadstore.c
@@ -58,6 +58,18 @@ static bool kvmppc_check_vsx_disabled(struct kvm_vcpu *vcpu)
 }
 #endif /* CONFIG_VSX */
 
+#ifdef CONFIG_ALTIVEC
+static bool kvmppc_check_altivec_disabled(struct kvm_vcpu *vcpu)
+{
+   if (!(kvmppc_get_msr(vcpu) & MSR_VEC)) {
+   kvmppc_core_queue_vec_unavail(vcpu);
+   return true;
+   }
+
+   return false;
+}
+#endif /* CONFIG_ALTIVEC */
+
 /*
  * XXX to do:
  * lfiwax, lfiwzx
@@ -98,6 +110,7 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
vcpu->arch.mmio_vsx_copy_type = KVMPPC_VSX_COPY_NONE;
vcpu->arch.mmio_sp64_extend = 0;
vcpu->arch.mmio_sign_extend = 0;
+   vcpu->arch.mmio_vmx_copy_nums = 0;
 
switch (get_op(inst)) {
case 31:
@@ -459,6 +472,27 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
 rs, 4, 1);
break;
 #endif /* CONFIG_VSX */
+
+#ifdef CONFIG_ALTIVEC
+   case OP_31_XOP_LVX:
+   if (kvmppc_check_altivec_disabled(vcpu))
+   return EMULATE_DONE;
+   vcpu->arch.vaddr_accessed = ~0xFULL;
+   vcpu->arch.mmio_vmx_copy_nums = 2;
+   emulated = kvmppc_handle_load128_by2x64(run, vcpu,
+   KVM_MMIO_REG_VMX|rt, 1);
+   break;
+
+   case OP_31_XOP_STVX:
+   if (kvmppc_check_altivec_disabled(vcpu))
+   return EMULATE_DONE;
+   vcpu->arch.vaddr_accessed = ~0xFULL;
+ 

[PATCH v3 0/1] Implements MMIO emulation for lvx/stvx instructions

2018-01-31 Thread Jose Ricardo Ziviani
v3:
  - Added Reported-by in the commit message

v2:
  - kvmppc_get_vsr_word_offset() moved back to its original place
  - EA AND ~0xF, following ISA.
  - fixed BE/LE cases

TESTS:

For testing purposes I wrote a small program that performs stvx/lvx using the
program's virtual memory and using MMIO. Load/Store into virtual memory is the
model I use to check if MMIO results are correct (because only MMIO is emulated
by KVM).

Results:

HOST LE - GUEST BE
address: 0x10034850010
0x2143658778563412
io_address: 0x3fff89a2
0x2143658778563412

HOST LE - GUEST LE
address: 0x10033a20010
0x1234567887654321
io_address: 0x3fffb538
0x1234567887654321

HOST BE - GUEST BE
address: 0x1002c4a0010
0x2143658778563412
io_address: 0x3ffface4
0x2143658778563412

HOST BR - GUEST LE
address: 0x100225e0010
0x1234567887654321
io_address: 0x3fff7fcb
0x1234567887654321

This patch implements MMIO emulation for two instructions: lvx and stvx.

Jose Ricardo Ziviani (1):
  KVM: PPC: Book3S: Add MMIO emulation for VMX instructions

 arch/powerpc/include/asm/kvm_host.h   |   2 +
 arch/powerpc/include/asm/kvm_ppc.h|   4 +
 arch/powerpc/include/asm/ppc-opcode.h |   6 ++
 arch/powerpc/kvm/emulate_loadstore.c  |  34 
 arch/powerpc/kvm/powerpc.c| 153 +-
 5 files changed, 198 insertions(+), 1 deletion(-)

-- 
2.14.3



[PATCH v2 1/1] KVM: PPC: Book3S: Add MMIO emulation for VMX instructions

2018-01-29 Thread Jose Ricardo Ziviani
This patch provides the MMIO load/store vector indexed
X-Form emulation.

Instructions implemented:
lvx: the quadword in storage addressed by the result of EA &
0x___fff0 is loaded into VRT.

stvx: the contents of VRS are stored into the quadword in storage
addressed by the result of EA & 0x___fff0.

Signed-off-by: Jose Ricardo Ziviani <jos...@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/kvm_host.h   |   2 +
 arch/powerpc/include/asm/kvm_ppc.h|   4 +
 arch/powerpc/include/asm/ppc-opcode.h |   6 ++
 arch/powerpc/kvm/emulate_loadstore.c  |  34 
 arch/powerpc/kvm/powerpc.c| 153 +-
 5 files changed, 198 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index 3aa5b577cd60..2c14a78c61a4 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -690,6 +690,7 @@ struct kvm_vcpu_arch {
u8 mmio_vsx_offset;
u8 mmio_vsx_copy_type;
u8 mmio_vsx_tx_sx_enabled;
+   u8 mmio_vmx_copy_nums;
u8 osi_needed;
u8 osi_enabled;
u8 papr_enabled;
@@ -800,6 +801,7 @@ struct kvm_vcpu_arch {
 #define KVM_MMIO_REG_QPR   0x0040
 #define KVM_MMIO_REG_FQPR  0x0060
 #define KVM_MMIO_REG_VSX   0x0080
+#define KVM_MMIO_REG_VMX   0x00a0
 
 #define __KVM_HAVE_ARCH_WQP
 #define __KVM_HAVE_CREATE_DEVICE
diff --git a/arch/powerpc/include/asm/kvm_ppc.h 
b/arch/powerpc/include/asm/kvm_ppc.h
index 9db18287b5f4..7765a800ddae 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -81,6 +81,10 @@ extern int kvmppc_handle_loads(struct kvm_run *run, struct 
kvm_vcpu *vcpu,
 extern int kvmppc_handle_vsx_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
unsigned int rt, unsigned int bytes,
int is_default_endian, int mmio_sign_extend);
+extern int kvmppc_handle_load128_by2x64(struct kvm_run *run,
+   struct kvm_vcpu *vcpu, unsigned int rt, int is_default_endian);
+extern int kvmppc_handle_store128_by2x64(struct kvm_run *run,
+   struct kvm_vcpu *vcpu, unsigned int rs, int is_default_endian);
 extern int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
   u64 val, unsigned int bytes,
   int is_default_endian);
diff --git a/arch/powerpc/include/asm/ppc-opcode.h 
b/arch/powerpc/include/asm/ppc-opcode.h
index ab5c1588b487..f1083bcf449c 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -156,6 +156,12 @@
 #define OP_31_XOP_LFDX  599
 #define OP_31_XOP_LFDUX631
 
+/* VMX Vector Load Instructions */
+#define OP_31_XOP_LVX   103
+
+/* VMX Vector Store Instructions */
+#define OP_31_XOP_STVX  231
+
 #define OP_LWZ  32
 #define OP_STFS 52
 #define OP_STFSU 53
diff --git a/arch/powerpc/kvm/emulate_loadstore.c 
b/arch/powerpc/kvm/emulate_loadstore.c
index af833531af31..7c92b6867f3e 100644
--- a/arch/powerpc/kvm/emulate_loadstore.c
+++ b/arch/powerpc/kvm/emulate_loadstore.c
@@ -58,6 +58,18 @@ static bool kvmppc_check_vsx_disabled(struct kvm_vcpu *vcpu)
 }
 #endif /* CONFIG_VSX */
 
+#ifdef CONFIG_ALTIVEC
+static bool kvmppc_check_altivec_disabled(struct kvm_vcpu *vcpu)
+{
+   if (!(kvmppc_get_msr(vcpu) & MSR_VEC)) {
+   kvmppc_core_queue_vec_unavail(vcpu);
+   return true;
+   }
+
+   return false;
+}
+#endif /* CONFIG_ALTIVEC */
+
 /*
  * XXX to do:
  * lfiwax, lfiwzx
@@ -98,6 +110,7 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
vcpu->arch.mmio_vsx_copy_type = KVMPPC_VSX_COPY_NONE;
vcpu->arch.mmio_sp64_extend = 0;
vcpu->arch.mmio_sign_extend = 0;
+   vcpu->arch.mmio_vmx_copy_nums = 0;
 
switch (get_op(inst)) {
case 31:
@@ -459,6 +472,27 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
 rs, 4, 1);
break;
 #endif /* CONFIG_VSX */
+
+#ifdef CONFIG_ALTIVEC
+   case OP_31_XOP_LVX:
+   if (kvmppc_check_altivec_disabled(vcpu))
+   return EMULATE_DONE;
+   vcpu->arch.vaddr_accessed = ~0xFULL;
+   vcpu->arch.mmio_vmx_copy_nums = 2;
+   emulated = kvmppc_handle_load128_by2x64(run, vcpu,
+   KVM_MMIO_REG_VMX|rt, 1);
+   break;
+
+   case OP_31_XOP_STVX:
+   if (kvmppc_check_altivec_disabled(vcpu))
+   return EMULATE_DONE;
+   vcpu->arch.vaddr_accessed = ~0xFULL;
+   vcpu->arch.mmio_vmx_copy_nums = 2;
+   emulated = kvmppc_handle_store128_by2x64(run, vcpu,

[PATCH v2 0/1] Implements MMIO emulation for lvx/stvx instructions

2018-01-29 Thread Jose Ricardo Ziviani
v2:
  - kvmppc_get_vsr_word_offset() moved back to its original place
  - EA AND ~0xF, following ISA.
  - fixed BE/LE cases

TESTS:

For testing purposes I wrote a small program that performs stvx/lvx using the
program's virtual memory and using MMIO. Load/Store into virtual memory is the
model I use to check if MMIO results are correct (because only MMIO is emulated
by KVM).

Results:

HOST LE - GUEST BE
address: 0x10034850010
0x2143658778563412
io_address: 0x3fff89a2
0x2143658778563412

HOST LE - GUEST LE
address: 0x10033a20010
0x1234567887654321
io_address: 0x3fffb538
0x1234567887654321

HOST BE - GUEST BE
address: 0x1002c4a0010
0x2143658778563412
io_address: 0x3ffface4
0x2143658778563412

HOST BR - GUEST LE
address: 0x100225e0010
0x1234567887654321
io_address: 0x3fff7fcb
0x1234567887654321

This patch implements MMIO emulation for two instructions: lvx and stvx.

Jose Ricardo Ziviani (1):
  KVM: PPC: Book3S: Add MMIO emulation for VMX instructions

 arch/powerpc/include/asm/kvm_host.h   |   2 +
 arch/powerpc/include/asm/kvm_ppc.h|   4 +
 arch/powerpc/include/asm/ppc-opcode.h |   6 ++
 arch/powerpc/kvm/emulate_loadstore.c  |  34 
 arch/powerpc/kvm/powerpc.c| 153 +-
 5 files changed, 198 insertions(+), 1 deletion(-)

-- 
2.14.3



[PATCH RESEND 1/1] KVM: PPC: Book3S: Add MMIO emulation for VMX instructions

2018-01-08 Thread Jose Ricardo Ziviani
This patch provides the MMIO load/store vector indexed
X-Form emulation.

Instructions implemented: lvx, stvx

Signed-off-by: Jose Ricardo Ziviani <jos...@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/kvm_host.h   |   2 +
 arch/powerpc/include/asm/kvm_ppc.h|   4 +
 arch/powerpc/include/asm/ppc-opcode.h |   6 ++
 arch/powerpc/kvm/emulate_loadstore.c  |  32 +++
 arch/powerpc/kvm/powerpc.c| 162 ++
 5 files changed, 189 insertions(+), 17 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index 3aa5b577cd60..2c14a78c61a4 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -690,6 +690,7 @@ struct kvm_vcpu_arch {
u8 mmio_vsx_offset;
u8 mmio_vsx_copy_type;
u8 mmio_vsx_tx_sx_enabled;
+   u8 mmio_vmx_copy_nums;
u8 osi_needed;
u8 osi_enabled;
u8 papr_enabled;
@@ -800,6 +801,7 @@ struct kvm_vcpu_arch {
 #define KVM_MMIO_REG_QPR   0x0040
 #define KVM_MMIO_REG_FQPR  0x0060
 #define KVM_MMIO_REG_VSX   0x0080
+#define KVM_MMIO_REG_VMX   0x00a0
 
 #define __KVM_HAVE_ARCH_WQP
 #define __KVM_HAVE_CREATE_DEVICE
diff --git a/arch/powerpc/include/asm/kvm_ppc.h 
b/arch/powerpc/include/asm/kvm_ppc.h
index 941c2a3f231b..28c203003519 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -81,6 +81,10 @@ extern int kvmppc_handle_loads(struct kvm_run *run, struct 
kvm_vcpu *vcpu,
 extern int kvmppc_handle_vsx_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
unsigned int rt, unsigned int bytes,
int is_default_endian, int mmio_sign_extend);
+extern int kvmppc_handle_load128_by2x64(struct kvm_run *run,
+   struct kvm_vcpu *vcpu, unsigned int rt, int is_default_endian);
+extern int kvmppc_handle_store128_by2x64(struct kvm_run *run,
+   struct kvm_vcpu *vcpu, unsigned int rs, int is_default_endian);
 extern int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
   u64 val, unsigned int bytes,
   int is_default_endian);
diff --git a/arch/powerpc/include/asm/ppc-opcode.h 
b/arch/powerpc/include/asm/ppc-opcode.h
index ce0930d68857..a51febca08c5 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -156,6 +156,12 @@
 #define OP_31_XOP_LFDX  599
 #define OP_31_XOP_LFDUX631
 
+/* VMX Vector Load Instructions */
+#define OP_31_XOP_LVX   103
+
+/* VMX Vector Store Instructions */
+#define OP_31_XOP_STVX  231
+
 #define OP_LWZ  32
 #define OP_STFS 52
 #define OP_STFSU 53
diff --git a/arch/powerpc/kvm/emulate_loadstore.c 
b/arch/powerpc/kvm/emulate_loadstore.c
index af833531af31..40fbc14809cb 100644
--- a/arch/powerpc/kvm/emulate_loadstore.c
+++ b/arch/powerpc/kvm/emulate_loadstore.c
@@ -58,6 +58,18 @@ static bool kvmppc_check_vsx_disabled(struct kvm_vcpu *vcpu)
 }
 #endif /* CONFIG_VSX */
 
+#ifdef CONFIG_ALTIVEC
+static bool kvmppc_check_altivec_disabled(struct kvm_vcpu *vcpu)
+{
+   if (!(kvmppc_get_msr(vcpu) & MSR_VEC)) {
+   kvmppc_core_queue_vec_unavail(vcpu);
+   return true;
+   }
+
+   return false;
+}
+#endif /* CONFIG_ALTIVEC */
+
 /*
  * XXX to do:
  * lfiwax, lfiwzx
@@ -98,6 +110,7 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
vcpu->arch.mmio_vsx_copy_type = KVMPPC_VSX_COPY_NONE;
vcpu->arch.mmio_sp64_extend = 0;
vcpu->arch.mmio_sign_extend = 0;
+   vcpu->arch.mmio_vmx_copy_nums = 0;
 
switch (get_op(inst)) {
case 31:
@@ -459,6 +472,25 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
 rs, 4, 1);
break;
 #endif /* CONFIG_VSX */
+
+#ifdef CONFIG_ALTIVEC
+   case OP_31_XOP_LVX:
+   if (kvmppc_check_altivec_disabled(vcpu))
+   return EMULATE_DONE;
+   vcpu->arch.mmio_vmx_copy_nums = 2;
+   emulated = kvmppc_handle_load128_by2x64(run, vcpu,
+   KVM_MMIO_REG_VMX|rt, 1);
+   break;
+
+   case OP_31_XOP_STVX:
+   if (kvmppc_check_altivec_disabled(vcpu))
+   return EMULATE_DONE;
+   vcpu->arch.mmio_vmx_copy_nums = 2;
+   emulated = kvmppc_handle_store128_by2x64(run, vcpu,
+   rs, 1);
+   break;
+#endif /* CONFIG_ALTIVEC */
+
default:
emulated = EMULATE_FAIL;
break;
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 1915e86cef6f..7d0f60359ee0 100644
--- a/arch/powerpc/kvm/powe

[PATCH RESEND 0/1] Implements MMIO emulation for lvx/stvx instructions

2018-01-08 Thread Jose Ricardo Ziviani
This patch implements MMIO emulation for two instructions: lvx and stvx.

NOTE: I'm resending copying now kvm-...@vger.kernel.org.

Thanks.

Jose Ricardo Ziviani (1):
  KVM: PPC: Book3S: Add MMIO emulation for VMX instructions

 arch/powerpc/include/asm/kvm_host.h   |   2 +
 arch/powerpc/include/asm/kvm_ppc.h|   4 +
 arch/powerpc/include/asm/ppc-opcode.h |   6 ++
 arch/powerpc/kvm/emulate_loadstore.c  |  32 +++
 arch/powerpc/kvm/powerpc.c| 162 ++
 5 files changed, 189 insertions(+), 17 deletions(-)

-- 
2.14.1



[PATCH v3 1/1] powerpc/pseries: Make RAS IRQ explicitly dependent on DLPAR WQ

2018-01-03 Thread Jose Ricardo Ziviani
The hotplug engine uses its own workqueue to handle IRQ requests, the
problem is that such workqueue is initialized after init_ras_IRQ, which
will cause a kernel panic if any hotplug interruption is issued in that
period of time.

This patch makes RAS IRQ registration explicitly dependent on DLPAR
workqueue and adds a check to make sure that the workqueue is not
initialized more than once.

Reported-by: Min Deng <md...@redhat.com>
Reported-by: Daniel Henrique Barboza <danie...@linux.vnet.ibm.com>
Tested-by: Jose Ricardo Ziviani <jos...@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <m...@ellerman.id.au>
---
 arch/powerpc/platforms/pseries/dlpar.c   | 21 ++---
 arch/powerpc/platforms/pseries/pseries.h |  2 ++
 arch/powerpc/platforms/pseries/ras.c |  3 ++-
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/dlpar.c 
b/arch/powerpc/platforms/pseries/dlpar.c
index 6e35780c5962..a0b20c03f078 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -574,11 +574,26 @@ static ssize_t dlpar_show(struct class *class, struct 
class_attribute *attr,
 
 static CLASS_ATTR_RW(dlpar);
 
-static int __init pseries_dlpar_init(void)
+int __init dlpar_workqueue_init(void)
 {
+   if (pseries_hp_wq)
+   return 0;
+
pseries_hp_wq = alloc_workqueue("pseries hotplug workqueue",
-   WQ_UNBOUND, 1);
+   WQ_UNBOUND, 1);
+
+   return pseries_hp_wq ? 0 : -ENOMEM;
+}
+
+static int __init dlpar_sysfs_init(void)
+{
+   int rc;
+
+   rc = dlpar_workqueue_init();
+   if (rc)
+   return rc;
+
return sysfs_create_file(kernel_kobj, _attr_dlpar.attr);
 }
-machine_device_initcall(pseries, pseries_dlpar_init);
+machine_device_initcall(pseries, dlpar_sysfs_init);
 
diff --git a/arch/powerpc/platforms/pseries/pseries.h 
b/arch/powerpc/platforms/pseries/pseries.h
index 4470a3194311..1ae1d9f4dbe9 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -98,4 +98,6 @@ static inline unsigned long cmo_get_page_size(void)
return CMO_PageSize;
 }
 
+int dlpar_workqueue_init(void);
+
 #endif /* _PSERIES_PSERIES_H */
diff --git a/arch/powerpc/platforms/pseries/ras.c 
b/arch/powerpc/platforms/pseries/ras.c
index 4923ffe230cf..81d8614e7379 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -69,7 +69,8 @@ static int __init init_ras_IRQ(void)
/* Hotplug Events */
np = of_find_node_by_path("/event-sources/hot-plug-events");
if (np != NULL) {
-   request_event_sources_irqs(np, ras_hotplug_interrupt,
+   if (dlpar_workqueue_init() == 0)
+   request_event_sources_irqs(np, ras_hotplug_interrupt,
   "RAS_HOTPLUG");
of_node_put(np);
}
-- 
2.14.1



[PATCH v3 0/1] Make RAS IRQ explicitly dependent on DLPAR workqueue

2018-01-03 Thread Jose Ricardo Ziviani
This patch replaces "[PATCH v2 0/1] Increase dlpar initcall priority"

1. Testing without this patch, using QEMU:

[0.022800] UDP-Lite hash table entries: 2048 (order: 0, 65536 bytes)
[0.022865] NET: Registered protocol family 1
[0.023435] Unpacking initramfs...
(qemu) object_add memory-backend-ram,id=mem1,size=10G   

(qemu) device_add pc-dimm,id=dimm1,memdev=mem1  

[0.095354] Unable to handle kernel paging request for data at address 
0xf94d03007c421378
[0.095409] Faulting instruction address: 0xc012d744
[0.095450] Oops: Kernel access of bad area, sig: 11 [#1]
[0.095482] LE SMP NR_CPUS=2048 NUMA pSeries
[0.095516] Modules linked in:
[0.095542] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.15.0-rc2-ziviani+ #26
[0.095592] task: (ptrval) task.stack: (ptrval)
[0.095634] NIP:  c012d744 LR: c012d744 CTR: 
[0.095683] REGS: (ptrval) TRAP: 0380   Not tainted  
(4.15.0-rc2-ziviani+)
[0.095729] MSR:  80009033 <SF,EE,ME,IR,DR,RI,LE>  CR: 28088042  
XER: 2004
[0.095780] CFAR: c012d3c4 SOFTE: 0 
[0.095780] GPR00: c012d744 c000fffefb90 c1290c00 
 
[0.095780] GPR04: 7fff c000fe20bb40 03d7 
c12cdd78 
[0.095780] GPR08: 0001  fed1 
1001 
[0.095780] GPR12: c00c6800 cfac c000d1a8 
8000 
[0.095780] GPR16:  c000fea0a007 c0c44d78 
0001 
[0.095780] GPR20:  c0e2c8a8 c1452af8 
 
[0.095780] GPR24: c1452af0 c000fffefe70  
c0e2c8a8 
[0.095780] GPR28: 0800  c000fe20bb40 
f94d03007c421378 
[0.096174] NIP [c012d744] __queue_work+0xd4/0x5c0
[0.096207] LR [c012d744] __queue_work+0xd4/0x5c0
[0.096241] Call Trace:
[0.096258] [c000fffefb90] [c012d744] __queue_work+0xd4/0x5c0 
(unreliable)
[0.096308] [c000fffefc70] [c012dce4] queue_work_on+0xb4/0xf0
snip
[0.097459] ---[ end trace b527625ce4033fad ]---
[0.099233] 
[1.099254] Kernel panic - not syncing: Fatal exception in interrupt
[1.103312] Rebooting in 10 seconds..

2. Testing with this patch, with QEMU again:

[0.023086] NET: Registered protocol family 1
[0.023664] Unpacking initramfs...
(qemu) object_add memory-backend-ram,id=mem1,size=10G   

(qemu) device_add pc-dimm,id=dimm1,memdev=mem1  

[0.163178] pseries-hotplug-mem: Attempting to hot-add 40 LMB(s) at index 
8010
[0.163416] radix-mmu: Mapped 0xc001-0xc0011000 with 
2.00 MiB pages
[0.163830] radix-mmu: Mapped 0xc0011000-0xc0012000 with 
2.00 MiB pages
snip
[0.189706] pseries-hotplug-mem: Memory at 1 (drc index 8010) 
was hot-added
[0.189753] pseries-hotplug-mem: Memory at 11000 (drc index 8011) 
was hot-added
snip
...normal initialization

(qemu)  info memory-devices 
Memory device [dimm]: "dimm1"
  addr: 0x1
  slot: 0
  node: 0
  size: 10737418240
  memdev: /objects/mem1
  hotplugged: true
  hotpluggable: true

Jose Ricardo Ziviani (1):
  powerpc/pseries: Make RAS IRQ explicitly dependent on DLPAR WQ

 arch/powerpc/platforms/pseries/dlpar.c   | 21 ++---
 arch/powerpc/platforms/pseries/pseries.h |  2 ++
 arch/powerpc/platforms/pseries/ras.c |  3 ++-
 3 files changed, 22 insertions(+), 4 deletions(-)

-- 
2.14.1



[PATCH RESEND 1/1] KVM: PPC: Book3S: Add MMIO emulation for VMX instructions

2017-12-26 Thread Jose Ricardo Ziviani
This patch provides the MMIO load/store vector indexed
X-Form emulation.

Instructions implemented: lvx, stvx

Signed-off-by: Jose Ricardo Ziviani <jos...@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/kvm_host.h   |   2 +
 arch/powerpc/include/asm/kvm_ppc.h|   4 +
 arch/powerpc/include/asm/ppc-opcode.h |   6 ++
 arch/powerpc/kvm/emulate_loadstore.c  |  32 +++
 arch/powerpc/kvm/powerpc.c| 162 ++
 5 files changed, 189 insertions(+), 17 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index 3aa5b577cd60..2c14a78c61a4 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -690,6 +690,7 @@ struct kvm_vcpu_arch {
u8 mmio_vsx_offset;
u8 mmio_vsx_copy_type;
u8 mmio_vsx_tx_sx_enabled;
+   u8 mmio_vmx_copy_nums;
u8 osi_needed;
u8 osi_enabled;
u8 papr_enabled;
@@ -800,6 +801,7 @@ struct kvm_vcpu_arch {
 #define KVM_MMIO_REG_QPR   0x0040
 #define KVM_MMIO_REG_FQPR  0x0060
 #define KVM_MMIO_REG_VSX   0x0080
+#define KVM_MMIO_REG_VMX   0x00a0
 
 #define __KVM_HAVE_ARCH_WQP
 #define __KVM_HAVE_CREATE_DEVICE
diff --git a/arch/powerpc/include/asm/kvm_ppc.h 
b/arch/powerpc/include/asm/kvm_ppc.h
index 941c2a3f231b..28c203003519 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -81,6 +81,10 @@ extern int kvmppc_handle_loads(struct kvm_run *run, struct 
kvm_vcpu *vcpu,
 extern int kvmppc_handle_vsx_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
unsigned int rt, unsigned int bytes,
int is_default_endian, int mmio_sign_extend);
+extern int kvmppc_handle_load128_by2x64(struct kvm_run *run,
+   struct kvm_vcpu *vcpu, unsigned int rt, int is_default_endian);
+extern int kvmppc_handle_store128_by2x64(struct kvm_run *run,
+   struct kvm_vcpu *vcpu, unsigned int rs, int is_default_endian);
 extern int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
   u64 val, unsigned int bytes,
   int is_default_endian);
diff --git a/arch/powerpc/include/asm/ppc-opcode.h 
b/arch/powerpc/include/asm/ppc-opcode.h
index ce0930d68857..a51febca08c5 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -156,6 +156,12 @@
 #define OP_31_XOP_LFDX  599
 #define OP_31_XOP_LFDUX631
 
+/* VMX Vector Load Instructions */
+#define OP_31_XOP_LVX   103
+
+/* VMX Vector Store Instructions */
+#define OP_31_XOP_STVX  231
+
 #define OP_LWZ  32
 #define OP_STFS 52
 #define OP_STFSU 53
diff --git a/arch/powerpc/kvm/emulate_loadstore.c 
b/arch/powerpc/kvm/emulate_loadstore.c
index af833531af31..40fbc14809cb 100644
--- a/arch/powerpc/kvm/emulate_loadstore.c
+++ b/arch/powerpc/kvm/emulate_loadstore.c
@@ -58,6 +58,18 @@ static bool kvmppc_check_vsx_disabled(struct kvm_vcpu *vcpu)
 }
 #endif /* CONFIG_VSX */
 
+#ifdef CONFIG_ALTIVEC
+static bool kvmppc_check_altivec_disabled(struct kvm_vcpu *vcpu)
+{
+   if (!(kvmppc_get_msr(vcpu) & MSR_VEC)) {
+   kvmppc_core_queue_vec_unavail(vcpu);
+   return true;
+   }
+
+   return false;
+}
+#endif /* CONFIG_ALTIVEC */
+
 /*
  * XXX to do:
  * lfiwax, lfiwzx
@@ -98,6 +110,7 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
vcpu->arch.mmio_vsx_copy_type = KVMPPC_VSX_COPY_NONE;
vcpu->arch.mmio_sp64_extend = 0;
vcpu->arch.mmio_sign_extend = 0;
+   vcpu->arch.mmio_vmx_copy_nums = 0;
 
switch (get_op(inst)) {
case 31:
@@ -459,6 +472,25 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
 rs, 4, 1);
break;
 #endif /* CONFIG_VSX */
+
+#ifdef CONFIG_ALTIVEC
+   case OP_31_XOP_LVX:
+   if (kvmppc_check_altivec_disabled(vcpu))
+   return EMULATE_DONE;
+   vcpu->arch.mmio_vmx_copy_nums = 2;
+   emulated = kvmppc_handle_load128_by2x64(run, vcpu,
+   KVM_MMIO_REG_VMX|rt, 1);
+   break;
+
+   case OP_31_XOP_STVX:
+   if (kvmppc_check_altivec_disabled(vcpu))
+   return EMULATE_DONE;
+   vcpu->arch.mmio_vmx_copy_nums = 2;
+   emulated = kvmppc_handle_store128_by2x64(run, vcpu,
+   rs, 1);
+   break;
+#endif /* CONFIG_ALTIVEC */
+
default:
emulated = EMULATE_FAIL;
break;
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 1915e86cef6f..7d0f60359ee0 100644
--- a/arch/powerpc/kvm/powe

[PATCH RESEND 0/1] Implements MMIO emulation for lvx/stvx instructions

2017-12-26 Thread Jose Ricardo Ziviani
This patch implements MMIO emulation for two instructions: lvx and stvx.

Thanks.

Jose Ricardo Ziviani (1):
  KVM: PPC: Book3S: Add MMIO emulation for VMX instructions

 arch/powerpc/include/asm/kvm_host.h   |   2 +
 arch/powerpc/include/asm/kvm_ppc.h|   4 +
 arch/powerpc/include/asm/ppc-opcode.h |   6 ++
 arch/powerpc/kvm/emulate_loadstore.c  |  32 +++
 arch/powerpc/kvm/powerpc.c| 162 ++
 5 files changed, 189 insertions(+), 17 deletions(-)

-- 
2.14.1



[PATCH v2 1/1] powerpc/pseries: increase pseries_dlpar_init initcall priority

2017-12-26 Thread Jose Ricardo Ziviani
The hotplug engine uses its own workqueue to handle IRQ requests, the
problem is that such workqueue is initialized after init_ras_IRQ, which
will cause a kernel panic if any hotplug interruption is issued in that
period of time.

This patch changes the dlpar initcall registration to make sure it will
be initialized before init_ras_IRQ.

Signed-off-by: Jose Ricardo Ziviani <jos...@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/dlpar.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/pseries/dlpar.c 
b/arch/powerpc/platforms/pseries/dlpar.c
index 6e35780c5962..1f9ae1d0b2be 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -580,5 +580,5 @@ static int __init pseries_dlpar_init(void)
WQ_UNBOUND, 1);
return sysfs_create_file(kernel_kobj, _attr_dlpar.attr);
 }
-machine_device_initcall(pseries, pseries_dlpar_init);
+machine_arch_initcall(pseries, pseries_dlpar_init);
 
-- 
2.14.1



[PATCH v2 0/1] Increase dlpar initcall priority

2017-12-26 Thread Jose Ricardo Ziviani
This patch replaces the "powerpc/pseries: Use the system workqueue as fallback
to hotplug workqueue".

Jose Ricardo Ziviani (1):
  powerpc/pseries: increase pseries_dlpar_init initcall priority

 arch/powerpc/platforms/pseries/dlpar.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

-- 
2.14.1



[PATCH 0/1] Uses the system workqueue as fallback

2017-12-21 Thread Jose Ricardo Ziviani
In order to avoid kernel panic after memory hotplug in early stages of the boot
process (which the kernel is already able to handle IRQs), this patch uses the
system workqueue as a fallback to the hotplug workqueue.

After this patch I'm not able to reproduce the problem and the memory is
successfuly plugged at any stage in the boot process.

Thank you

Error scenario:

Booting Linux via __start() @ 0x0200 ...
[0.00] Detected Power 8 processor 
[0.00] Warning: Processor - this hardware has not undergone testing by 
Red Hat and might not be certified. Please consult https://hardware.redhat.com 
for certified hardware.
 -> smp_release_cpus()
spinning_secondaries = 3
 <- smp_release_cpus()
Linux ppc64le
#1 SMP Wed Nov 2[0.021319] Unable to handle kernel paging request for data 
at address 0x0100
[0.021379] Faulting instruction address: 0xc015c420
[0.021423] Oops: Kernel access of bad area, sig: 11 [#1]
[0.021457] LE SMP NR_CPUS=2048 NUMA pSeries
[0.021493] Modules linked in:
[0.021522] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.14.0-9.el7a.ppc64le 
#1
[0.021572] task: c0047bb8 task.stack: c0047bbc
[0.021615] NIP:  c015c420 LR: c015cae4 CTR: 
[0.021666] REGS: c0047ffeb920 TRAP: 0380   Not tainted  
(4.14.0-9.el7a.ppc64le)
[0.021715] MSR:  82009033 <SF,VEC,EE,ME,IR,DR,RI,LE>  CR: 2842  
XER: 2000
[0.021769] CFAR: c015cae0 SOFTE: 0 
[0.021769] GPR00: c015cae4 c0047ffebba0 c14ca600 
0800 
[0.021769] GPR04:  c0047e1e5000 01a0 
c00e19e0 
[0.021769] GPR08: 000fffe1  000fffe0 
02001001 
[0.021769] GPR12: c00e0ea0 c7ac c000d0b8 
 
[0.021769] GPR16:  c0047e1e5000  
 
[0.021769] GPR20:  0001 0002 
0015 
[0.021769] GPR24: c001fdc075b8 0001 c001fdc07400 
 
[0.021769] GPR28: 0800   
0800 
[0.022196] NIP [c015c420] __queue_work+0x80/0x690
[0.022231] LR [c015cae4] queue_work_on+0xb4/0xf0
[0.022264] Call Trace:
[0.022283] [c0047ffebba0] [c017d948] ttwu_do_wakeup+0x228/0x290 
(unreliable)
[0.022334] [c0047ffebc90] [c015cae4] queue_work_on+0xb4/0xf0
[0.022377] [c0047ffebcd0] [c00e36d0] 
queue_hotplug_event+0xe0/0x160
[0.022428] [c0047ffebd20] [c00e0fe0] 
ras_hotplug_interrupt+0x140/0x160
[0.022480] [c0047ffebdb0] [c01d0a20] 
__handle_irq_event_percpu+0xa0/0x330
...
[1.024963] Kernel panic - not syncing: Fatal exception in interrupt
[1.027080] Rebooting in 10 seconds..

Test case 1: Hotplug during the boot process, after the hotplug wq
initialization

0.554391] rtas_flash: no firmware flash support
[0.554464] >>>>>>>>>>>>>>>> [devlog pseries_hp_wq] ALLOCed
[0.555021] Initialise system trusted keyrings
...
...
Welcome to Red Hat Enterprise Linux Server 7.4 (Maipo) dracut-033-502.el7 
(Initramfs)!
...
[  OK  ] Started dracut cmdline hook.
 Starting dracut pre-udev hook...
(qemu) object_add memory-backend-ram,id=mem1,size=10G
(qemu) device_add pc-dimm,id=dimm1,memdev=mem1
[0.754432] >>>>>>>>>>>>>>>> [devlog pseries_hp_wq] 0xfec52400L
[0.765465] pseries-hotplug-mem: Attempting to hot-add 40 LMB(s) at index 
8010
[0.765710] radix-mmu: Mapped 0xc001-0xc0011000 with 
2.00 MiB pages
...
(qemu) info memory-devices
Memory device [dimm]: "dimm1"
  addr: 0x1
  slot: 0
  node: 0
  size: 10737418240
  memdev: /objects/mem1
  hotplugged: true
  hotpluggable: true

Test case 2: Hotplug during the boot process, before the hotplug wq
initialization

[   [0.028103] NET: Registered protocol family 1
[0.028745] Unpacking initramfs...
(qemu) object_add memory-backend-ram,id=mem1,size=10G
(qemu) device_add pc-dimm,id=dimm1,memdev=mem1
[0.407070] >>>>>>>>>>>>>>>> [devlog pseries_hp_wq] 0x0 (using system wq)
[0.407420] pseries-hotplug-mem: Attempting to hot-add 40 LMB(s) at index 
8010
[0.407749] radix-mmu: Mapped 0xc001-0xc0011000 with 
2.00 MiB pages
...  0.627554] rtas_flash: no firmware flash support
[0.627674] >>>>>>>>>>>>>>>> [devlog pseries_hp_wq] ALLOCed
[0.628451] Initialise system trusted keyrings
...
(qemu) info memory-devices
Memory device [dimm]: "dimm1"
  addr: 0x1
  slot: 0
  node: 0
  size: 10737418240
  memdev: /objects/mem1
  hotplugged: tr

[PATCH 1/1] powerpc/pseries: Use the system workqueue as fallback to hotplug workqueue

2017-12-21 Thread Jose Ricardo Ziviani
The hotplug engine uses its own workqueue to handle IRQ requests, the
problem is that such workqueue is initialized not so early in the boot
process.

Thus, when the kernel is ready to handle IRQ requests, after the system
workqueue is initialized, we have a timeframe where any hotplug issued
by the client will result in a kernel panic. That timeframe goes until
the hotplug workqueue is initialized.

It would be good to have the hotplug workqueue initialized as soon as
the system workqueue but I don't think it is possible. So, this patch
uses the system workqueue as a fallback the handle such IRQs.

Signed-off-by: Jose Ricardo Ziviani <jos...@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/dlpar.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/pseries/dlpar.c 
b/arch/powerpc/platforms/pseries/dlpar.c
index 6e35780c5962..0474aa14b5f6 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -399,7 +399,15 @@ void queue_hotplug_event(struct pseries_hp_errorlog 
*hp_errlog,
work->errlog = hp_errlog_copy;
work->hp_completion = hotplug_done;
work->rc = rc;
-   queue_work(pseries_hp_wq, (struct work_struct *)work);
+
+   /* The hotplug workqueue may happen to be NULL at the moment
+* this code is executed, during the boot phase. So, in this
+* scenario, we can fallback to the system workqueue.
+*/
+   if (unlikely(pseries_hp_wq == NULL))
+   schedule_work((struct work_struct *)work);
+   else
+   queue_work(pseries_hp_wq, (struct work_struct *)work);
} else {
*rc = -ENOMEM;
kfree(hp_errlog_copy);
-- 
2.14.1



[PATCH 1/1] KVM: PPC: Book3S: Add MMIO emulation for VMX instructions

2017-10-13 Thread Jose Ricardo Ziviani
This patch provides the MMIO load/store vector indexed
X-Form emulation.

Instructions implemented: lvx, stvx

Signed-off-by: Jose Ricardo Ziviani <jos...@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/kvm_host.h   |   2 +
 arch/powerpc/include/asm/kvm_ppc.h|   4 +
 arch/powerpc/include/asm/ppc-opcode.h |   6 ++
 arch/powerpc/kvm/emulate_loadstore.c  |  32 +++
 arch/powerpc/kvm/powerpc.c| 162 ++
 5 files changed, 189 insertions(+), 17 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index e372ed871c51..a28922c4a2c7 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -692,6 +692,7 @@ struct kvm_vcpu_arch {
u8 mmio_vsx_offset;
u8 mmio_vsx_copy_type;
u8 mmio_vsx_tx_sx_enabled;
+   u8 mmio_vmx_copy_nums;
u8 osi_needed;
u8 osi_enabled;
u8 papr_enabled;
@@ -802,6 +803,7 @@ struct kvm_vcpu_arch {
 #define KVM_MMIO_REG_QPR   0x0040
 #define KVM_MMIO_REG_FQPR  0x0060
 #define KVM_MMIO_REG_VSX   0x0080
+#define KVM_MMIO_REG_VMX   0x00a0
 
 #define __KVM_HAVE_ARCH_WQP
 #define __KVM_HAVE_CREATE_DEVICE
diff --git a/arch/powerpc/include/asm/kvm_ppc.h 
b/arch/powerpc/include/asm/kvm_ppc.h
index ba5fadd6f3c9..c444d1614b9c 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -81,6 +81,10 @@ extern int kvmppc_handle_loads(struct kvm_run *run, struct 
kvm_vcpu *vcpu,
 extern int kvmppc_handle_vsx_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
unsigned int rt, unsigned int bytes,
int is_default_endian, int mmio_sign_extend);
+extern int kvmppc_handle_load128_by2x64(struct kvm_run *run,
+   struct kvm_vcpu *vcpu, unsigned int rt, int is_default_endian);
+extern int kvmppc_handle_store128_by2x64(struct kvm_run *run,
+   struct kvm_vcpu *vcpu, unsigned int rs, int is_default_endian);
 extern int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
   u64 val, unsigned int bytes,
   int is_default_endian);
diff --git a/arch/powerpc/include/asm/ppc-opcode.h 
b/arch/powerpc/include/asm/ppc-opcode.h
index ce0930d68857..a51febca08c5 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -156,6 +156,12 @@
 #define OP_31_XOP_LFDX  599
 #define OP_31_XOP_LFDUX631
 
+/* VMX Vector Load Instructions */
+#define OP_31_XOP_LVX   103
+
+/* VMX Vector Store Instructions */
+#define OP_31_XOP_STVX  231
+
 #define OP_LWZ  32
 #define OP_STFS 52
 #define OP_STFSU 53
diff --git a/arch/powerpc/kvm/emulate_loadstore.c 
b/arch/powerpc/kvm/emulate_loadstore.c
index af833531af31..40fbc14809cb 100644
--- a/arch/powerpc/kvm/emulate_loadstore.c
+++ b/arch/powerpc/kvm/emulate_loadstore.c
@@ -58,6 +58,18 @@ static bool kvmppc_check_vsx_disabled(struct kvm_vcpu *vcpu)
 }
 #endif /* CONFIG_VSX */
 
+#ifdef CONFIG_ALTIVEC
+static bool kvmppc_check_altivec_disabled(struct kvm_vcpu *vcpu)
+{
+   if (!(kvmppc_get_msr(vcpu) & MSR_VEC)) {
+   kvmppc_core_queue_vec_unavail(vcpu);
+   return true;
+   }
+
+   return false;
+}
+#endif /* CONFIG_ALTIVEC */
+
 /*
  * XXX to do:
  * lfiwax, lfiwzx
@@ -98,6 +110,7 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
vcpu->arch.mmio_vsx_copy_type = KVMPPC_VSX_COPY_NONE;
vcpu->arch.mmio_sp64_extend = 0;
vcpu->arch.mmio_sign_extend = 0;
+   vcpu->arch.mmio_vmx_copy_nums = 0;
 
switch (get_op(inst)) {
case 31:
@@ -459,6 +472,25 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
 rs, 4, 1);
break;
 #endif /* CONFIG_VSX */
+
+#ifdef CONFIG_ALTIVEC
+   case OP_31_XOP_LVX:
+   if (kvmppc_check_altivec_disabled(vcpu))
+   return EMULATE_DONE;
+   vcpu->arch.mmio_vmx_copy_nums = 2;
+   emulated = kvmppc_handle_load128_by2x64(run, vcpu,
+   KVM_MMIO_REG_VMX|rt, 1);
+   break;
+
+   case OP_31_XOP_STVX:
+   if (kvmppc_check_altivec_disabled(vcpu))
+   return EMULATE_DONE;
+   vcpu->arch.mmio_vmx_copy_nums = 2;
+   emulated = kvmppc_handle_store128_by2x64(run, vcpu,
+   rs, 1);
+   break;
+#endif /* CONFIG_ALTIVEC */
+
default:
emulated = EMULATE_FAIL;
break;
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 3480faaf1ef8..6f3b49cd6634 100644
--- a/arch/powerpc/kvm/powe

[PATCH 0/1] powerpc: Implements MMIO emulation for lvx/stvx instructions

2017-10-13 Thread Jose Ricardo Ziviani
Hello!

This patch implements MMIO emulation for two instructions: lvx and stvx.

Thank you!

Jose Ricardo Ziviani (1):
  KVM: PPC: Book3S: Add MMIO emulation for VMX instructions

 arch/powerpc/include/asm/kvm_host.h   |   2 +
 arch/powerpc/include/asm/kvm_ppc.h|   4 +
 arch/powerpc/include/asm/ppc-opcode.h |   6 ++
 arch/powerpc/kvm/emulate_loadstore.c  |  32 +++
 arch/powerpc/kvm/powerpc.c| 162 ++
 5 files changed, 189 insertions(+), 17 deletions(-)

-- 
2.11.0



[PATCH] powerpc/eeh: Disable EEH stack dump by default

2017-09-19 Thread Jose Ricardo Ziviani
Today, each EEH causes a stack dump to be printed in the logs. In
production environment it's not quite necessary. Thus, this patch
adds a new command line argument in order to enable the stack
dump for debugging purposes.

For example, instead of the following:

[  131.778661] EEH: Frozen PHB#2-PE#fd detected
[  131.778672] EEH: PE location: N/A, PHB location: N/A
[  131.778677] CPU: 21 PID: 10098 Comm: lspci Not tainted ...
[  131.778680] Call Trace:
[  131.778686] [c003a140bab0] [c0beb58c] dump_stack+...

[  131.778770] EEH: Detected PCI bus error on PHB#2-PE#fd
[  131.778775] EEH: This PCI device has failed 1 times in the last hour
...

we will have this by default:

[12777.175880] EEH: Frozen PHB#2-PE#fd detected
[12777.175893] EEH: PE location: N/A, PHB location: N/A
[12777.175922] EEH: Detected PCI bus error on PHB#2-PE#fd
[12777.175931] EEH: This PCI device has failed 2 times in the last hour
...

Signed-off-by: Jose Ricardo Ziviani <jos...@linux.vnet.ibm.com>
---
 arch/powerpc/kernel/eeh.c | 26 +++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index 9e81678..4336c3b1 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -157,6 +157,19 @@ static int __init eeh_setup(char *str)
 __setup("eeh=", eeh_setup);
 
 /*
+ * It's not necessary to dump the stack trace when an EEH occours
+ * in the production environment. For debugging, the command line
+ * option "enable_eeh_stacktrace" brings the stack dump back
+ */
+static bool eeh_show_stacktrace;
+static int __init enable_eeh_stacktrace(char *p)
+{
+   eeh_show_stacktrace = true;
+   return 0;
+}
+early_param("enable_eeh_stacktrace", enable_eeh_stacktrace);
+
+/*
  * This routine captures assorted PCI configuration space data
  * for the indicated PCI device, and puts them into a buffer
  * for RTAS error logging.
@@ -407,7 +420,10 @@ static int eeh_phb_check_failure(struct eeh_pe *pe)
 
pr_err("EEH: PHB#%x failure detected, location: %s\n",
phb_pe->phb->global_number, eeh_pe_loc_get(phb_pe));
-   dump_stack();
+
+   if (eeh_show_stacktrace)
+   dump_stack();
+
eeh_send_failure_event(phb_pe);
 
return 1;
@@ -504,7 +520,9 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
eeh_driver_name(dev), eeh_pci_name(dev));
printk(KERN_ERR "EEH: Might be infinite loop in %s 
driver\n",
eeh_driver_name(dev));
-   dump_stack();
+
+   if (eeh_show_stacktrace)
+   dump_stack();
}
goto dn_unlock;
}
@@ -572,7 +590,9 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
   pe->phb->global_number, pe->addr);
pr_err("EEH: PE location: %s, PHB location: %s\n",
   eeh_pe_loc_get(pe), eeh_pe_loc_get(phb_pe));
-   dump_stack();
+
+   if (eeh_show_stacktrace)
+   dump_stack();
 
eeh_send_failure_event(pe);
 
-- 
2.7.4



[PATCH RFC] powerpc: Implements MMIO emulation for lvx/stvx instructions

2017-08-29 Thread Jose Ricardo Ziviani
Hello!

This patch implements MMIO emulation for two instructions: lvx and stvx. I 
started to implement other instructions but I'd like to have this reviewed 
beforehand because this is my first patch here and I'll certainly have some 
rework/fixes :-).

Note: stvx is only storing 8 bytes, for some reason the code 
"vcpu->arch.paddr_accessed += run->mmio.len;", which adds the 8-byte offset 
after the first write is not making any difference (interesting that it works 
for load operations). I'm still investigating it but any idea about it will be 
appreciated.

Thank you very much,

Jose Ricardo Ziviani (1):
  KVM: PPC: Book3S: Add MMIO emulation for VMX instructions

 arch/powerpc/include/asm/kvm_host.h   |   2 +
 arch/powerpc/include/asm/kvm_ppc.h|   4 +
 arch/powerpc/include/asm/ppc-opcode.h |   6 ++
 arch/powerpc/kvm/emulate_loadstore.c  |  32 +++
 arch/powerpc/kvm/powerpc.c| 162 ++
 5 files changed, 189 insertions(+), 17 deletions(-)

-- 
2.7.4