KVM: PPC: BOOK3S: Remove open coded make_dsisr in alignment handler
Use make_dsisr instead of open coding it. This also have the added benefit of handling alignment interrupt on additional instructions. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:

committed by
Alexander Graf

parent
7310f3a5b0
commit
ddca156ae6
@@ -81,4 +81,38 @@ static inline unsigned int get_oc(u32 inst)
|
|||||||
{
|
{
|
||||||
return (inst >> 11) & 0x7fff;
|
return (inst >> 11) & 0x7fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define IS_XFORM(inst) (get_op(inst) == 31)
|
||||||
|
#define IS_DSFORM(inst) (get_op(inst) >= 56)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a DSISR value from the instruction
|
||||||
|
*/
|
||||||
|
static inline unsigned make_dsisr(unsigned instr)
|
||||||
|
{
|
||||||
|
unsigned dsisr;
|
||||||
|
|
||||||
|
|
||||||
|
/* bits 6:15 --> 22:31 */
|
||||||
|
dsisr = (instr & 0x03ff0000) >> 16;
|
||||||
|
|
||||||
|
if (IS_XFORM(instr)) {
|
||||||
|
/* bits 29:30 --> 15:16 */
|
||||||
|
dsisr |= (instr & 0x00000006) << 14;
|
||||||
|
/* bit 25 --> 17 */
|
||||||
|
dsisr |= (instr & 0x00000040) << 8;
|
||||||
|
/* bits 21:24 --> 18:21 */
|
||||||
|
dsisr |= (instr & 0x00000780) << 3;
|
||||||
|
} else {
|
||||||
|
/* bit 5 --> 17 */
|
||||||
|
dsisr |= (instr & 0x04000000) >> 12;
|
||||||
|
/* bits 1: 4 --> 18:21 */
|
||||||
|
dsisr |= (instr & 0x78000000) >> 17;
|
||||||
|
/* bits 30:31 --> 12:13 */
|
||||||
|
if (IS_DSFORM(instr))
|
||||||
|
dsisr |= (instr & 0x00000003) << 18;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dsisr;
|
||||||
|
}
|
||||||
#endif /* __ASM_PPC_DISASSEMBLE_H__ */
|
#endif /* __ASM_PPC_DISASSEMBLE_H__ */
|
||||||
|
@@ -25,14 +25,13 @@
|
|||||||
#include <asm/cputable.h>
|
#include <asm/cputable.h>
|
||||||
#include <asm/emulated_ops.h>
|
#include <asm/emulated_ops.h>
|
||||||
#include <asm/switch_to.h>
|
#include <asm/switch_to.h>
|
||||||
|
#include <asm/disassemble.h>
|
||||||
|
|
||||||
struct aligninfo {
|
struct aligninfo {
|
||||||
unsigned char len;
|
unsigned char len;
|
||||||
unsigned char flags;
|
unsigned char flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IS_XFORM(inst) (((inst) >> 26) == 31)
|
|
||||||
#define IS_DSFORM(inst) (((inst) >> 26) >= 56)
|
|
||||||
|
|
||||||
#define INVALID { 0, 0 }
|
#define INVALID { 0, 0 }
|
||||||
|
|
||||||
@@ -191,37 +190,6 @@ static struct aligninfo aligninfo[128] = {
|
|||||||
INVALID, /* 11 1 1111 */
|
INVALID, /* 11 1 1111 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a DSISR value from the instruction
|
|
||||||
*/
|
|
||||||
static inline unsigned make_dsisr(unsigned instr)
|
|
||||||
{
|
|
||||||
unsigned dsisr;
|
|
||||||
|
|
||||||
|
|
||||||
/* bits 6:15 --> 22:31 */
|
|
||||||
dsisr = (instr & 0x03ff0000) >> 16;
|
|
||||||
|
|
||||||
if (IS_XFORM(instr)) {
|
|
||||||
/* bits 29:30 --> 15:16 */
|
|
||||||
dsisr |= (instr & 0x00000006) << 14;
|
|
||||||
/* bit 25 --> 17 */
|
|
||||||
dsisr |= (instr & 0x00000040) << 8;
|
|
||||||
/* bits 21:24 --> 18:21 */
|
|
||||||
dsisr |= (instr & 0x00000780) << 3;
|
|
||||||
} else {
|
|
||||||
/* bit 5 --> 17 */
|
|
||||||
dsisr |= (instr & 0x04000000) >> 12;
|
|
||||||
/* bits 1: 4 --> 18:21 */
|
|
||||||
dsisr |= (instr & 0x78000000) >> 17;
|
|
||||||
/* bits 30:31 --> 12:13 */
|
|
||||||
if (IS_DSFORM(instr))
|
|
||||||
dsisr |= (instr & 0x00000003) << 18;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dsisr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The dcbz (data cache block zero) instruction
|
* The dcbz (data cache block zero) instruction
|
||||||
* gives an alignment fault if used on non-cacheable
|
* gives an alignment fault if used on non-cacheable
|
||||||
|
@@ -634,44 +634,7 @@ unprivileged:
|
|||||||
|
|
||||||
u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst)
|
u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst)
|
||||||
{
|
{
|
||||||
u32 dsisr = 0;
|
return make_dsisr(inst);
|
||||||
|
|
||||||
/*
|
|
||||||
* This is what the spec says about DSISR bits (not mentioned = 0):
|
|
||||||
*
|
|
||||||
* 12:13 [DS] Set to bits 30:31
|
|
||||||
* 15:16 [X] Set to bits 29:30
|
|
||||||
* 17 [X] Set to bit 25
|
|
||||||
* [D/DS] Set to bit 5
|
|
||||||
* 18:21 [X] Set to bits 21:24
|
|
||||||
* [D/DS] Set to bits 1:4
|
|
||||||
* 22:26 Set to bits 6:10 (RT/RS/FRT/FRS)
|
|
||||||
* 27:31 Set to bits 11:15 (RA)
|
|
||||||
*/
|
|
||||||
|
|
||||||
switch (get_op(inst)) {
|
|
||||||
/* D-form */
|
|
||||||
case OP_LFS:
|
|
||||||
case OP_LFD:
|
|
||||||
case OP_STFD:
|
|
||||||
case OP_STFS:
|
|
||||||
dsisr |= (inst >> 12) & 0x4000; /* bit 17 */
|
|
||||||
dsisr |= (inst >> 17) & 0x3c00; /* bits 18:21 */
|
|
||||||
break;
|
|
||||||
/* X-form */
|
|
||||||
case 31:
|
|
||||||
dsisr |= (inst << 14) & 0x18000; /* bits 15:16 */
|
|
||||||
dsisr |= (inst << 8) & 0x04000; /* bit 17 */
|
|
||||||
dsisr |= (inst << 3) & 0x03c00; /* bits 18:21 */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printk(KERN_INFO "KVM: Unaligned instruction 0x%x\n", inst);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
dsisr |= (inst >> 16) & 0x03ff; /* bits 22:31 */
|
|
||||||
|
|
||||||
return dsisr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst)
|
ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst)
|
||||||
|
Reference in New Issue
Block a user