Skip to content
Permalink
Browse files
KVM: PPC: Use the ppc_inst type
The ppc_inst type was added to help cope with the addition of prefixed
instructions to the ISA. Convert KVM to use this new type for dealing
wiht instructions. For now do not try to add further support for
prefixed instructions.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
  • Loading branch information
iamjpn authored and intel-lab-lkp committed Aug 20, 2020
1 parent 9123e3a commit 1025d48f0402f678140989df94e55a62f67c1d48
Show file tree
Hide file tree
Showing 32 changed files with 237 additions and 210 deletions.
@@ -10,75 +10,82 @@
#define __ASM_PPC_DISASSEMBLE_H__

#include <linux/types.h>
#include <asm/inst.h>

static inline unsigned int get_op(u32 inst)
static inline unsigned int get_op(struct ppc_inst inst)
{
return inst >> 26;
return ppc_inst_val(inst) >> 26;
}

static inline unsigned int get_xop(u32 inst)
static inline unsigned int get_xop(struct ppc_inst inst)
{
return (inst >> 1) & 0x3ff;
return (ppc_inst_val(inst) >> 1) & 0x3ff;
}

static inline unsigned int get_sprn(u32 inst)
static inline unsigned int get_sprn(struct ppc_inst inst)
{
return ((inst >> 16) & 0x1f) | ((inst >> 6) & 0x3e0);
u32 word = ppc_inst_val(inst);

return ((word >> 16) & 0x1f) | ((word >> 6) & 0x3e0);
}

static inline unsigned int get_dcrn(u32 inst)
static inline unsigned int get_dcrn(struct ppc_inst inst)
{
return ((inst >> 16) & 0x1f) | ((inst >> 6) & 0x3e0);
u32 word = ppc_inst_val(inst);

return ((word >> 16) & 0x1f) | ((word >> 6) & 0x3e0);
}

static inline unsigned int get_tmrn(u32 inst)
static inline unsigned int get_tmrn(struct ppc_inst inst)
{
return ((inst >> 16) & 0x1f) | ((inst >> 6) & 0x3e0);
u32 word = ppc_inst_val(inst);

return ((word >> 16) & 0x1f) | ((word >> 6) & 0x3e0);
}

static inline unsigned int get_rt(u32 inst)
static inline unsigned int get_rt(struct ppc_inst inst)
{
return (inst >> 21) & 0x1f;
return (ppc_inst_val(inst) >> 21) & 0x1f;
}

static inline unsigned int get_rs(u32 inst)
static inline unsigned int get_rs(struct ppc_inst inst)
{
return (inst >> 21) & 0x1f;
return (ppc_inst_val(inst) >> 21) & 0x1f;
}

static inline unsigned int get_ra(u32 inst)
static inline unsigned int get_ra(struct ppc_inst inst)
{
return (inst >> 16) & 0x1f;
return (ppc_inst_val(inst) >> 16) & 0x1f;
}

static inline unsigned int get_rb(u32 inst)
static inline unsigned int get_rb(struct ppc_inst inst)
{
return (inst >> 11) & 0x1f;
return (ppc_inst_val(inst) >> 11) & 0x1f;
}

static inline unsigned int get_rc(u32 inst)
static inline unsigned int get_rc(struct ppc_inst inst)
{
return inst & 0x1;
return ppc_inst_val(inst) & 0x1;
}

static inline unsigned int get_ws(u32 inst)
static inline unsigned int get_ws(struct ppc_inst inst)
{
return (inst >> 11) & 0x1f;
return (ppc_inst_val(inst) >> 11) & 0x1f;
}

static inline unsigned int get_d(u32 inst)
static inline unsigned int get_d(struct ppc_inst inst)
{
return inst & 0xffff;
return ppc_inst_val(inst) & 0xffff;
}

static inline unsigned int get_oc(u32 inst)
static inline unsigned int get_oc(struct ppc_inst inst)
{
return (inst >> 11) & 0x7fff;
return (ppc_inst_val(inst) >> 11) & 0x7fff;
}

static inline unsigned int get_tx_or_sx(u32 inst)
static inline unsigned int get_tx_or_sx(struct ppc_inst inst)
{
return (inst) & 0x1;
return (ppc_inst_val(inst)) & 0x1;
}

#define IS_XFORM(inst) (get_op(inst) == 31)
@@ -87,29 +94,30 @@ static inline unsigned int get_tx_or_sx(u32 inst)
/*
* Create a DSISR value from the instruction
*/
static inline unsigned make_dsisr(unsigned instr)
static inline unsigned make_dsisr(struct ppc_inst instr)
{
unsigned dsisr;
u32 word = ppc_inst_val(instr);


/* bits 6:15 --> 22:31 */
dsisr = (instr & 0x03ff0000) >> 16;
dsisr = (word & 0x03ff0000) >> 16;

if (IS_XFORM(instr)) {
/* bits 29:30 --> 15:16 */
dsisr |= (instr & 0x00000006) << 14;
dsisr |= (word & 0x00000006) << 14;
/* bit 25 --> 17 */
dsisr |= (instr & 0x00000040) << 8;
dsisr |= (word & 0x00000040) << 8;
/* bits 21:24 --> 18:21 */
dsisr |= (instr & 0x00000780) << 3;
dsisr |= (word & 0x00000780) << 3;
} else {
/* bit 5 --> 17 */
dsisr |= (instr & 0x04000000) >> 12;
dsisr |= (word & 0x04000000) >> 12;
/* bits 1: 4 --> 18:21 */
dsisr |= (instr & 0x78000000) >> 17;
dsisr |= (word & 0x78000000) >> 17;
/* bits 30:31 --> 12:13 */
if (IS_DSFORM(instr))
dsisr |= (instr & 0x00000003) << 18;
dsisr |= (word & 0x00000003) << 18;
}

return dsisr;
@@ -268,8 +268,8 @@ extern void kvmhv_emulate_tm_rollback(struct kvm_vcpu *vcpu);

extern void kvmppc_entry_trampoline(void);
extern void kvmppc_hv_entry_trampoline(void);
extern u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst);
extern ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst);
extern u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, struct ppc_inst inst);
extern ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, struct ppc_inst inst);
extern int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd);
extern void kvmppc_pr_init_default_hcalls(struct kvm *kvm);
extern int kvmppc_hcall_impl_pr(unsigned long cmd);
@@ -134,6 +134,7 @@ struct kvmppc_host_state {
#endif
};

#include <asm/inst.h>
struct kvmppc_book3s_shadow_vcpu {
bool in_use;
ulong gpr[14];
@@ -146,7 +147,7 @@ struct kvmppc_book3s_shadow_vcpu {
ulong shadow_srr1;
ulong fault_dar;
u32 fault_dsisr;
u32 last_inst;
struct ppc_inst last_inst;

#ifdef CONFIG_PPC_BOOK3S_32
u32 sr[16]; /* Guest SRs */
@@ -25,6 +25,7 @@
#include <asm/cacheflush.h>
#include <asm/hvcall.h>
#include <asm/mce.h>
#include <asm/inst.h>

#define KVM_MAX_VCPUS NR_CPUS
#define KVM_MAX_VCORES NR_CPUS
@@ -751,7 +752,7 @@ struct kvm_vcpu_arch {
u8 prodded;
u8 doorbell_request;
u8 irq_pending; /* Used by XIVE to signal pending guest irqs */
u32 last_inst;
struct ppc_inst last_inst;

struct rcuwait *waitp;
struct kvmppc_vcore *vcore;
@@ -810,7 +811,7 @@ struct kvm_vcpu_arch {
u64 busy_stolen;
u64 busy_preempt;

u32 emul_inst;
struct ppc_inst emul_inst;

u32 online;

@@ -29,6 +29,8 @@
#include <asm/cpu_has_feature.h>
#endif

#include <asm/inst.h>

/*
* KVMPPC_INST_SW_BREAKPOINT is debug Instruction
* for supporting software breakpoint.
@@ -84,7 +86,7 @@ extern int kvmppc_handle_vsx_store(struct kvm_vcpu *vcpu,
int is_default_endian);

extern int kvmppc_load_last_inst(struct kvm_vcpu *vcpu,
enum instruction_fetch_type type, u32 *inst);
enum instruction_fetch_type type, struct ppc_inst *inst);

extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
bool data);
@@ -291,7 +293,7 @@ struct kvmppc_ops {
void (*destroy_vm)(struct kvm *kvm);
int (*get_smmu_info)(struct kvm *kvm, struct kvm_ppc_smmu_info *info);
int (*emulate_op)(struct kvm_vcpu *vcpu,
unsigned int inst, int *advance);
struct ppc_inst inst, int *advance);
int (*emulate_mtspr)(struct kvm_vcpu *vcpu, int sprn, ulong spr_val);
int (*emulate_mfspr)(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val);
void (*fast_vcpu_kick)(struct kvm_vcpu *vcpu);
@@ -320,20 +322,20 @@ extern struct kvmppc_ops *kvmppc_hv_ops;
extern struct kvmppc_ops *kvmppc_pr_ops;

static inline int kvmppc_get_last_inst(struct kvm_vcpu *vcpu,
enum instruction_fetch_type type, u32 *inst)
enum instruction_fetch_type type, struct ppc_inst *inst)
{
int ret = EMULATE_DONE;
u32 fetched_inst;
struct ppc_inst fetched_inst;

/* Load the instruction manually if it failed to do so in the
* exit path */
if (vcpu->arch.last_inst == KVM_INST_FETCH_FAILED)
if (ppc_inst_equal(vcpu->arch.last_inst, ppc_inst(KVM_INST_FETCH_FAILED)))
ret = kvmppc_load_last_inst(vcpu, type, &vcpu->arch.last_inst);

/* Write fetch_failed unswapped if the fetch failed */
if (ret == EMULATE_DONE)
fetched_inst = kvmppc_need_byteswap(vcpu) ?
swab32(vcpu->arch.last_inst) :
ppc_inst_swab(vcpu->arch.last_inst) :
vcpu->arch.last_inst;
else
fetched_inst = vcpu->arch.last_inst;
@@ -73,6 +73,8 @@
#include "../xmon/xmon_bpts.h"
#endif

#include <asm/inst.h>

#define STACK_PT_REGS_OFFSET(sym, val) \
DEFINE(sym, STACK_FRAME_OVERHEAD + offsetof(struct pt_regs, val))

0 comments on commit 1025d48

Please sign in to comment.