Commit 303d77a6 authored by Michael Ellerman's avatar Michael Ellerman

Merge branch 'topic/ppc-kvm' into next

Merge our KVM topic branch, this has been independently included in linux-next
for most of the development cycle.
parents 36e826b5 b7bce570
......@@ -26,6 +26,7 @@ powerpc
isa-versions
kaslr-booke32
mpc52xx
kvm-nested
papr_hcalls
pci_iov_resource_on_powernv
pmu-ebb
......
This diff is collapsed.
......@@ -82,6 +82,18 @@ config MSI_BITMAP_SELFTEST
bool "Run self-tests of the MSI bitmap code"
depends on DEBUG_KERNEL
config GUEST_STATE_BUFFER_TEST
def_tristate n
prompt "Enable Guest State Buffer unit tests"
depends on KUNIT
depends on KVM_BOOK3S_HV_POSSIBLE
default KUNIT_ALL_TESTS
help
The Guest State Buffer is a data format specified in the PAPR.
It is by hcalls to communicate the state of L2 guests between
the L1 and L0 hypervisors. Enable unit tests for the library
used to create and use guest state buffers.
config PPC_IRQ_SOFT_MASK_DEBUG
bool "Include extra checks for powerpc irq soft masking"
depends on PPC64
......
This diff is collapsed.
......@@ -100,6 +100,18 @@
#define H_COP_HW -74
#define H_STATE -75
#define H_IN_USE -77
#define H_INVALID_ELEMENT_ID -79
#define H_INVALID_ELEMENT_SIZE -80
#define H_INVALID_ELEMENT_VALUE -81
#define H_INPUT_BUFFER_NOT_DEFINED -82
#define H_INPUT_BUFFER_TOO_SMALL -83
#define H_OUTPUT_BUFFER_NOT_DEFINED -84
#define H_OUTPUT_BUFFER_TOO_SMALL -85
#define H_PARTITION_PAGE_TABLE_NOT_DEFINED -86
#define H_GUEST_VCPU_STATE_NOT_HV_OWNED -87
#define H_UNSUPPORTED_FLAG_START -256
#define H_UNSUPPORTED_FLAG_END -511
#define H_MULTI_THREADS_ACTIVE -9005
......@@ -381,6 +393,15 @@
#define H_ENTER_NESTED 0xF804
#define H_TLB_INVALIDATE 0xF808
#define H_COPY_TOFROM_GUEST 0xF80C
#define H_GUEST_GET_CAPABILITIES 0x460
#define H_GUEST_SET_CAPABILITIES 0x464
#define H_GUEST_CREATE 0x470
#define H_GUEST_CREATE_VCPU 0x474
#define H_GUEST_GET_STATE 0x478
#define H_GUEST_SET_STATE 0x47C
#define H_GUEST_RUN_VCPU 0x480
#define H_GUEST_COPY_MEMORY 0x484
#define H_GUEST_DELETE 0x488
/* Flags for H_SVM_PAGE_IN */
#define H_PAGE_IN_SHARED 0x1
......@@ -467,6 +488,15 @@
#define H_RPTI_PAGE_1G 0x08
#define H_RPTI_PAGE_ALL (-1UL)
/* Flags for H_GUEST_{S,G}_STATE */
#define H_GUEST_FLAGS_WIDE (1UL<<(63-0))
/* Flag values used for H_{S,G}SET_GUEST_CAPABILITIES */
#define H_GUEST_CAP_COPY_MEM (1UL<<(63-0))
#define H_GUEST_CAP_POWER9 (1UL<<(63-1))
#define H_GUEST_CAP_POWER10 (1UL<<(63-2))
#define H_GUEST_CAP_BITMAP2 (1UL<<(63-63))
#ifndef __ASSEMBLY__
#include <linux/types.h>
......
This diff is collapsed.
......@@ -624,7 +624,7 @@ static inline void copy_to_checkpoint(struct kvm_vcpu *vcpu)
extern int kvmppc_create_pte(struct kvm *kvm, pgd_t *pgtable, pte_t pte,
unsigned long gpa, unsigned int level,
unsigned long mmu_seq, unsigned int lpid,
unsigned long mmu_seq, u64 lpid,
unsigned long *rmapp, struct rmap_nested **n_rmap);
extern void kvmhv_insert_nest_rmap(struct kvm *kvm, unsigned long *rmapp,
struct rmap_nested **n_rmap);
......@@ -677,6 +677,12 @@ static inline pte_t *find_kvm_host_pte(struct kvm *kvm, unsigned long mmu_seq,
extern pte_t *find_kvm_nested_guest_pte(struct kvm *kvm, unsigned long lpid,
unsigned long ea, unsigned *hshift);
int kvmhv_nestedv2_vcpu_create(struct kvm_vcpu *vcpu, struct kvmhv_nestedv2_io *io);
void kvmhv_nestedv2_vcpu_free(struct kvm_vcpu *vcpu, struct kvmhv_nestedv2_io *io);
int kvmhv_nestedv2_flush_vcpu(struct kvm_vcpu *vcpu, u64 time_limit);
int kvmhv_nestedv2_set_ptbl_entry(unsigned long lpid, u64 dw0, u64 dw1);
int kvmhv_nestedv2_parse_output(struct kvm_vcpu *vcpu);
#endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */
#endif /* __ASM_KVM_BOOK3S_64_H__ */
......@@ -89,6 +89,16 @@ static inline ulong kvmppc_get_pc(struct kvm_vcpu *vcpu)
return vcpu->arch.regs.nip;
}
static inline void kvmppc_set_fpr(struct kvm_vcpu *vcpu, int i, u64 val)
{
vcpu->arch.fp.fpr[i][TS_FPROFFSET] = val;
}
static inline u64 kvmppc_get_fpr(struct kvm_vcpu *vcpu, int i)
{
return vcpu->arch.fp.fpr[i][TS_FPROFFSET];
}
#ifdef CONFIG_BOOKE
static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu)
{
......
......@@ -25,6 +25,7 @@
#include <asm/cacheflush.h>
#include <asm/hvcall.h>
#include <asm/mce.h>
#include <asm/guest-state-buffer.h>
#define __KVM_HAVE_ARCH_VCPU_DEBUGFS
......@@ -276,7 +277,7 @@ struct kvm_resize_hpt;
#define KVMPPC_SECURE_INIT_ABORT 0x4 /* H_SVM_INIT_ABORT issued */
struct kvm_arch {
unsigned int lpid;
u64 lpid;
unsigned int smt_mode; /* # vcpus per virtual core */
unsigned int emul_smt_mode; /* emualted SMT mode, on P9 */
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
......@@ -509,6 +510,23 @@ union xive_tma_w01 {
__be64 w01;
};
/* Nestedv2 H_GUEST_RUN_VCPU configuration */
struct kvmhv_nestedv2_config {
struct kvmppc_gs_buff_info vcpu_run_output_cfg;
struct kvmppc_gs_buff_info vcpu_run_input_cfg;
u64 vcpu_run_output_size;
};
/* Nestedv2 L1<->L0 communication state */
struct kvmhv_nestedv2_io {
struct kvmhv_nestedv2_config cfg;
struct kvmppc_gs_buff *vcpu_run_output;
struct kvmppc_gs_buff *vcpu_run_input;
struct kvmppc_gs_msg *vcpu_message;
struct kvmppc_gs_msg *vcore_message;
struct kvmppc_gs_bitmap valids;
};
struct kvm_vcpu_arch {
ulong host_stack;
u32 host_pid;
......@@ -829,6 +847,8 @@ struct kvm_vcpu_arch {
u64 nested_hfscr; /* HFSCR that the L1 requested for the nested guest */
u32 nested_vcpu_id;
gpa_t nested_io_gpr;
/* For nested APIv2 guests*/
struct kvmhv_nestedv2_io nestedv2_io;
#endif
#ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING
......
......@@ -615,6 +615,42 @@ static inline bool kvmhv_on_pseries(void)
{
return false;
}
#endif
#ifndef CONFIG_PPC_BOOK3S
static inline bool kvmhv_is_nestedv2(void)
{
return false;
}
static inline bool kvmhv_is_nestedv1(void)
{
return false;
}
static inline int kvmhv_nestedv2_reload_ptregs(struct kvm_vcpu *vcpu,
struct pt_regs *regs)
{
return 0;
}
static inline int kvmhv_nestedv2_mark_dirty_ptregs(struct kvm_vcpu *vcpu,
struct pt_regs *regs)
{
return 0;
}
static inline int kvmhv_nestedv2_mark_dirty(struct kvm_vcpu *vcpu, u16 iden)
{
return 0;
}
static inline int kvmhv_nestedv2_cached_reload(struct kvm_vcpu *vcpu, u16 iden)
{
return 0;
}
#endif
#ifdef CONFIG_KVM_XICS
......@@ -927,79 +963,85 @@ static inline bool kvmppc_shared_big_endian(struct kvm_vcpu *vcpu)
#endif
}
#define SPRNG_WRAPPER_GET(reg, bookehv_spr) \
#define KVMPPC_BOOKE_HV_SPRNG_ACCESSOR_GET(reg, bookehv_spr) \
static inline ulong kvmppc_get_##reg(struct kvm_vcpu *vcpu) \
{ \
return mfspr(bookehv_spr); \
} \
#define SPRNG_WRAPPER_SET(reg, bookehv_spr) \
#define KVMPPC_BOOKE_HV_SPRNG_ACCESSOR_SET(reg, bookehv_spr) \
static inline void kvmppc_set_##reg(struct kvm_vcpu *vcpu, ulong val) \
{ \
mtspr(bookehv_spr, val); \
} \
#define SHARED_WRAPPER_GET(reg, size) \
#define KVMPPC_VCPU_SHARED_REGS_ACCESSOR_GET(reg, size, iden) \
static inline u##size kvmppc_get_##reg(struct kvm_vcpu *vcpu) \
{ \
if (iden) \
WARN_ON(kvmhv_nestedv2_cached_reload(vcpu, iden) < 0); \
if (kvmppc_shared_big_endian(vcpu)) \
return be##size##_to_cpu(vcpu->arch.shared->reg); \
return be##size##_to_cpu((__be##size __force)vcpu->arch.shared->reg); \
else \
return le##size##_to_cpu(vcpu->arch.shared->reg); \
return le##size##_to_cpu((__le##size __force)vcpu->arch.shared->reg); \
} \
#define SHARED_WRAPPER_SET(reg, size) \
#define KVMPPC_VCPU_SHARED_REGS_ACCESSOR_SET(reg, size, iden) \
static inline void kvmppc_set_##reg(struct kvm_vcpu *vcpu, u##size val) \
{ \
if (kvmppc_shared_big_endian(vcpu)) \
vcpu->arch.shared->reg = cpu_to_be##size(val); \
vcpu->arch.shared->reg = (u##size __force)cpu_to_be##size(val); \
else \
vcpu->arch.shared->reg = cpu_to_le##size(val); \
vcpu->arch.shared->reg = (u##size __force)cpu_to_le##size(val); \
\
if (iden) \
kvmhv_nestedv2_mark_dirty(vcpu, iden); \
} \
#define SHARED_WRAPPER(reg, size) \
SHARED_WRAPPER_GET(reg, size) \
SHARED_WRAPPER_SET(reg, size) \
#define KVMPPC_VCPU_SHARED_REGS_ACCESSOR(reg, size, iden) \
KVMPPC_VCPU_SHARED_REGS_ACCESSOR_GET(reg, size, iden) \
KVMPPC_VCPU_SHARED_REGS_ACCESSOR_SET(reg, size, iden) \
#define SPRNG_WRAPPER(reg, bookehv_spr) \
SPRNG_WRAPPER_GET(reg, bookehv_spr) \
SPRNG_WRAPPER_SET(reg, bookehv_spr) \
#define KVMPPC_BOOKE_HV_SPRNG_ACCESSOR(reg, bookehv_spr) \
KVMPPC_BOOKE_HV_SPRNG_ACCESSOR_GET(reg, bookehv_spr) \
KVMPPC_BOOKE_HV_SPRNG_ACCESSOR_SET(reg, bookehv_spr) \
#ifdef CONFIG_KVM_BOOKE_HV
#define SHARED_SPRNG_WRAPPER(reg, size, bookehv_spr) \
SPRNG_WRAPPER(reg, bookehv_spr) \
#define KVMPPC_BOOKE_HV_SPRNG_OR_VCPU_SHARED_REGS_ACCESSOR(reg, size, bookehv_spr, iden) \
KVMPPC_BOOKE_HV_SPRNG_ACCESSOR(reg, bookehv_spr) \
#else
#define SHARED_SPRNG_WRAPPER(reg, size, bookehv_spr) \
SHARED_WRAPPER(reg, size) \
#define KVMPPC_BOOKE_HV_SPRNG_OR_VCPU_SHARED_REGS_ACCESSOR(reg, size, bookehv_spr, iden) \
KVMPPC_VCPU_SHARED_REGS_ACCESSOR(reg, size, iden) \
#endif
SHARED_WRAPPER(critical, 64)
SHARED_SPRNG_WRAPPER(sprg0, 64, SPRN_GSPRG0)
SHARED_SPRNG_WRAPPER(sprg1, 64, SPRN_GSPRG1)
SHARED_SPRNG_WRAPPER(sprg2, 64, SPRN_GSPRG2)
SHARED_SPRNG_WRAPPER(sprg3, 64, SPRN_GSPRG3)
SHARED_SPRNG_WRAPPER(srr0, 64, SPRN_GSRR0)
SHARED_SPRNG_WRAPPER(srr1, 64, SPRN_GSRR1)
SHARED_SPRNG_WRAPPER(dar, 64, SPRN_GDEAR)
SHARED_SPRNG_WRAPPER(esr, 64, SPRN_GESR)
SHARED_WRAPPER_GET(msr, 64)
KVMPPC_VCPU_SHARED_REGS_ACCESSOR(critical, 64, 0)
KVMPPC_BOOKE_HV_SPRNG_OR_VCPU_SHARED_REGS_ACCESSOR(sprg0, 64, SPRN_GSPRG0, KVMPPC_GSID_SPRG0)
KVMPPC_BOOKE_HV_SPRNG_OR_VCPU_SHARED_REGS_ACCESSOR(sprg1, 64, SPRN_GSPRG1, KVMPPC_GSID_SPRG1)
KVMPPC_BOOKE_HV_SPRNG_OR_VCPU_SHARED_REGS_ACCESSOR(sprg2, 64, SPRN_GSPRG2, KVMPPC_GSID_SPRG2)
KVMPPC_BOOKE_HV_SPRNG_OR_VCPU_SHARED_REGS_ACCESSOR(sprg3, 64, SPRN_GSPRG3, KVMPPC_GSID_SPRG3)
KVMPPC_BOOKE_HV_SPRNG_OR_VCPU_SHARED_REGS_ACCESSOR(srr0, 64, SPRN_GSRR0, KVMPPC_GSID_SRR0)
KVMPPC_BOOKE_HV_SPRNG_OR_VCPU_SHARED_REGS_ACCESSOR(srr1, 64, SPRN_GSRR1, KVMPPC_GSID_SRR1)
KVMPPC_BOOKE_HV_SPRNG_OR_VCPU_SHARED_REGS_ACCESSOR(dar, 64, SPRN_GDEAR, KVMPPC_GSID_DAR)
KVMPPC_BOOKE_HV_SPRNG_OR_VCPU_SHARED_REGS_ACCESSOR(esr, 64, SPRN_GESR, 0)
KVMPPC_VCPU_SHARED_REGS_ACCESSOR_GET(msr, 64, KVMPPC_GSID_MSR)
static inline void kvmppc_set_msr_fast(struct kvm_vcpu *vcpu, u64 val)
{
if (kvmppc_shared_big_endian(vcpu))
vcpu->arch.shared->msr = cpu_to_be64(val);
else
vcpu->arch.shared->msr = cpu_to_le64(val);
kvmhv_nestedv2_mark_dirty(vcpu, KVMPPC_GSID_MSR);
}
SHARED_WRAPPER(dsisr, 32)
SHARED_WRAPPER(int_pending, 32)
SHARED_WRAPPER(sprg4, 64)
SHARED_WRAPPER(sprg5, 64)
SHARED_WRAPPER(sprg6, 64)
SHARED_WRAPPER(sprg7, 64)
KVMPPC_VCPU_SHARED_REGS_ACCESSOR(dsisr, 32, KVMPPC_GSID_DSISR)
KVMPPC_VCPU_SHARED_REGS_ACCESSOR(int_pending, 32, 0)
KVMPPC_VCPU_SHARED_REGS_ACCESSOR(sprg4, 64, 0)
KVMPPC_VCPU_SHARED_REGS_ACCESSOR(sprg5, 64, 0)
KVMPPC_VCPU_SHARED_REGS_ACCESSOR(sprg6, 64, 0)
KVMPPC_VCPU_SHARED_REGS_ACCESSOR(sprg7, 64, 0)
static inline u32 kvmppc_get_sr(struct kvm_vcpu *vcpu, int nr)
{
......
......@@ -6,6 +6,7 @@
#include <linux/string.h>
#include <linux/irqflags.h>
#include <linux/delay.h>
#include <asm/hvcall.h>
#include <asm/paca.h>
......@@ -343,6 +344,212 @@ static inline long plpar_get_cpu_characteristics(struct h_cpu_char_result *p)
return rc;
}
static inline long plpar_guest_create(unsigned long flags, unsigned long *guest_id)
{
unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
unsigned long token;
long rc;
token = -1UL;
do {
rc = plpar_hcall(H_GUEST_CREATE, retbuf, flags, token);
if (rc == H_SUCCESS)
*guest_id = retbuf[0];
if (rc == H_BUSY) {
token = retbuf[0];
cond_resched();
}
if (H_IS_LONG_BUSY(rc)) {
token = retbuf[0];
msleep(get_longbusy_msecs(rc));
rc = H_BUSY;
}
} while (rc == H_BUSY);
return rc;
}
static inline long plpar_guest_create_vcpu(unsigned long flags,
unsigned long guest_id,
unsigned long vcpu_id)
{
long rc;
do {
rc = plpar_hcall_norets(H_GUEST_CREATE_VCPU, 0, guest_id, vcpu_id);
if (rc == H_BUSY)
cond_resched();
if (H_IS_LONG_BUSY(rc)) {
msleep(get_longbusy_msecs(rc));
rc = H_BUSY;
}
} while (rc == H_BUSY);
return rc;
}
static inline long plpar_guest_set_state(unsigned long flags,
unsigned long guest_id,
unsigned long vcpu_id,
unsigned long data_buffer,
unsigned long data_size,
unsigned long *failed_index)
{
unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
long rc;
while (true) {
rc = plpar_hcall(H_GUEST_SET_STATE, retbuf, flags, guest_id,
vcpu_id, data_buffer, data_size);
if (rc == H_BUSY) {
cpu_relax();
continue;
}
if (H_IS_LONG_BUSY(rc)) {
mdelay(get_longbusy_msecs(rc));
continue;
}
if (rc == H_INVALID_ELEMENT_ID)
*failed_index = retbuf[0];
else if (rc == H_INVALID_ELEMENT_SIZE)
*failed_index = retbuf[0];
else if (rc == H_INVALID_ELEMENT_VALUE)
*failed_index = retbuf[0];
break;
}
return rc;
}
static inline long plpar_guest_get_state(unsigned long flags,
unsigned long guest_id,
unsigned long vcpu_id,
unsigned long data_buffer,
unsigned long data_size,
unsigned long *failed_index)
{
unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
long rc;
while (true) {
rc = plpar_hcall(H_GUEST_GET_STATE, retbuf, flags, guest_id,
vcpu_id, data_buffer, data_size);
if (rc == H_BUSY) {
cpu_relax();
continue;
}
if (H_IS_LONG_BUSY(rc)) {
mdelay(get_longbusy_msecs(rc));
continue;
}
if (rc == H_INVALID_ELEMENT_ID)
*failed_index = retbuf[0];
else if (rc == H_INVALID_ELEMENT_SIZE)
*failed_index = retbuf[0];
else if (rc == H_INVALID_ELEMENT_VALUE)
*failed_index = retbuf[0];
break;
}
return rc;
}
static inline long plpar_guest_run_vcpu(unsigned long flags, unsigned long guest_id,
unsigned long vcpu_id, int *trap,
unsigned long *failed_index)
{
unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
long rc;
rc = plpar_hcall(H_GUEST_RUN_VCPU, retbuf, flags, guest_id, vcpu_id);
if (rc == H_SUCCESS)
*trap = retbuf[0];
else if (rc == H_INVALID_ELEMENT_ID)
*failed_index = retbuf[0];
else if (rc == H_INVALID_ELEMENT_SIZE)
*failed_index = retbuf[0];
else if (rc == H_INVALID_ELEMENT_VALUE)
*failed_index = retbuf[0];
return rc;
}
static inline long plpar_guest_delete(unsigned long flags, u64 guest_id)
{
long rc;
do {
rc = plpar_hcall_norets(H_GUEST_DELETE, flags, guest_id);
if (rc == H_BUSY)
cond_resched();
if (H_IS_LONG_BUSY(rc)) {
msleep(get_longbusy_msecs(rc));
rc = H_BUSY;
}
} while (rc == H_BUSY);
return rc;
}
static inline long plpar_guest_set_capabilities(unsigned long flags,
unsigned long capabilities)
{
unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
long rc;
do {
rc = plpar_hcall(H_GUEST_SET_CAPABILITIES, retbuf, flags, capabilities);
if (rc == H_BUSY)
cond_resched();
if (H_IS_LONG_BUSY(rc)) {
msleep(get_longbusy_msecs(rc));
rc = H_BUSY;
}
} while (rc == H_BUSY);
return rc;
}
static inline long plpar_guest_get_capabilities(unsigned long flags,
unsigned long *capabilities)
{
unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
long rc;
do {
rc = plpar_hcall(H_GUEST_GET_CAPABILITIES, retbuf, flags);
if (rc == H_BUSY)
cond_resched();
if (H_IS_LONG_BUSY(rc)) {
msleep(get_longbusy_msecs(rc));
rc = H_BUSY;
}
} while (rc == H_BUSY);
if (rc == H_SUCCESS)
*capabilities = retbuf[0];
return rc;
}
/*
* Wrapper to H_RPT_INVALIDATE hcall that handles return values appropriately
*
......@@ -355,7 +562,7 @@ static inline long plpar_get_cpu_characteristics(struct h_cpu_char_result *p)
* error recovery of killing the process/guest will be eventually
* needed.
*/
static inline long pseries_rpt_invalidate(u32 pid, u64 target, u64 type,
static inline long pseries_rpt_invalidate(u64 pid, u64 target, u64 type,
u64 page_sizes, u64 start, u64 end)
{
long rc;
......@@ -401,12 +608,68 @@ static inline long plpar_pte_read_4(unsigned long flags, unsigned long ptex,
return 0;
}
static inline long pseries_rpt_invalidate(u32 pid, u64 target, u64 type,
static inline long pseries_rpt_invalidate(u64 pid, u64 target, u64 type,
u64 page_sizes, u64 start, u64 end)
{
return 0;
}
static inline long plpar_guest_create_vcpu(unsigned long flags,
unsigned long guest_id,
unsigned long vcpu_id)
{
return 0;
}
static inline long plpar_guest_get_state(unsigned long flags,
unsigned long guest_id,
unsigned long vcpu_id,
unsigned long data_buffer,
unsigned long data_size,
unsigned long *failed_index)
{
return 0;
}
static inline long plpar_guest_set_state(unsigned long flags,
unsigned long guest_id,
unsigned long vcpu_id,
unsigned long data_buffer,
unsigned long data_size,
unsigned long *failed_index)
{
return 0;
}
static inline long plpar_guest_run_vcpu(unsigned long flags, unsigned long guest_id,
unsigned long vcpu_id, int *trap,
unsigned long *failed_index)
{
return 0;
}
static inline long plpar_guest_create(unsigned long flags, unsigned long *guest_id)
{
return 0;
}
static inline long plpar_guest_delete(unsigned long flags, u64 guest_id)
{
return 0;
}
static inline long plpar_guest_get_capabilities(unsigned long flags,
unsigned long *capabilities)
{
return 0;
}
static inline long plpar_guest_set_capabilities(unsigned long flags,
unsigned long capabilities)
{
return 0;
}
#endif /* CONFIG_PPC_PSERIES */
#endif /* _ASM_POWERPC_PLPAR_WRAPPERS_H */
......@@ -87,8 +87,12 @@ kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_HANDLER) += \
book3s_hv_ras.o \
book3s_hv_builtin.o \
book3s_hv_p9_perf.o \
book3s_hv_nestedv2.o \
guest-state-buffer.o \
$(kvm-book3s_64-builtin-tm-objs-y) \
$(kvm-book3s_64-builtin-xics-objs-y)
obj-$(CONFIG_GUEST_STATE_BUFFER_TEST) += test-guest-state-buffer.o
endif
kvm-book3s_64-objs-$(CONFIG_KVM_XICS) += \
......
......@@ -565,7 +565,7 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
regs->msr = kvmppc_get_msr(vcpu);
regs->srr0 = kvmppc_get_srr0(vcpu);
regs->srr1 = kvmppc_get_srr1(vcpu);
regs->pid = vcpu->arch.pid;
regs->pid = kvmppc_get_pid(vcpu);
regs->sprg0 = kvmppc_get_sprg0(vcpu);
regs->sprg1 = kvmppc_get_sprg1(vcpu);
regs->sprg2 = kvmppc_get_sprg2(vcpu);
......@@ -636,17 +636,17 @@ int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
break;
case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31:
i = id - KVM_REG_PPC_FPR0;
*val = get_reg_val(id, VCPU_FPR(vcpu, i));
*val = get_reg_val(id, kvmppc_get_fpr(vcpu, i));
break;
case KVM_REG_PPC_FPSCR:
*val = get_reg_val(id, vcpu->arch.fp.fpscr);
*val = get_reg_val(id, kvmppc_get_fpscr(vcpu));
break;
#ifdef CONFIG_VSX
case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31:
if (cpu_has_feature(CPU_FTR_VSX)) {
i = id - KVM_REG_PPC_VSR0;
val->vsxval[0] = vcpu->arch.fp.fpr[i][0];
val->vsxval[1] = vcpu->arch.fp.fpr[i][1];
val->vsxval[0] = kvmppc_get_vsx_fpr(vcpu, i, 0);
val->vsxval[1] = kvmppc_get_vsx_fpr(vcpu, i, 1);
} else {
r = -ENXIO;
}
......@@ -683,19 +683,19 @@ int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
*val = get_reg_val(id, vcpu->arch.fscr);
break;
case KVM_REG_PPC_TAR:
*val = get_reg_val(id, vcpu->arch.tar);
*val = get_reg_val(id, kvmppc_get_tar(vcpu));
break;
case KVM_REG_PPC_EBBHR:
*val = get_reg_val(id, vcpu->arch.ebbhr);
*val = get_reg_val(id, kvmppc_get_ebbhr(vcpu));
break;
case KVM_REG_PPC_EBBRR:
*val = get_reg_val(id, vcpu->arch.ebbrr);
*val = get_reg_val(id, kvmppc_get_ebbrr(vcpu));
break;
case KVM_REG_PPC_BESCR:
*val = get_reg_val(id, vcpu->arch.bescr);
*val = get_reg_val(id, kvmppc_get_bescr(vcpu));
break;
case KVM_REG_PPC_IC:
*val = get_reg_val(id, vcpu->arch.ic);
*val = get_reg_val(id, kvmppc_get_ic(vcpu));
break;
default:
r = -EINVAL;
......@@ -724,7 +724,7 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
break;
case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31:
i = id - KVM_REG_PPC_FPR0;
VCPU_FPR(vcpu, i) = set_reg_val(id, *val);
kvmppc_set_fpr(vcpu, i, set_reg_val(id, *val));
break;
case KVM_REG_PPC_FPSCR:
vcpu->arch.fp.fpscr = set_reg_val(id, *val);
......@@ -733,8 +733,8 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31:
if (cpu_has_feature(CPU_FTR_VSX)) {
i = id - KVM_REG_PPC_VSR0;
vcpu->arch.fp.fpr[i][0] = val->vsxval[0];
vcpu->arch.fp.fpr[i][1] = val->vsxval[1];
kvmppc_set_vsx_fpr(vcpu, i, 0, val->vsxval[0]);
kvmppc_set_vsx_fpr(vcpu, i, 1, val->vsxval[1]);
} else {
r = -ENXIO;
}
......@@ -765,22 +765,22 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
break;
#endif /* CONFIG_KVM_XIVE */
case KVM_REG_PPC_FSCR:
vcpu->arch.fscr = set_reg_val(id, *val);
kvmppc_set_fpscr(vcpu, set_reg_val(id, *val));
break;
case KVM_REG_PPC_TAR:
vcpu->arch.tar = set_reg_val(id, *val);
kvmppc_set_tar(vcpu, set_reg_val(id, *val));
break;
case KVM_REG_PPC_EBBHR:
vcpu->arch.ebbhr = set_reg_val(id, *val);
kvmppc_set_ebbhr(vcpu, set_reg_val(id, *val));
break;
case KVM_REG_PPC_EBBRR:
vcpu->arch.ebbrr = set_reg_val(id, *val);
kvmppc_set_ebbrr(vcpu, set_reg_val(id, *val));
break;
case KVM_REG_PPC_BESCR:
vcpu->arch.bescr = set_reg_val(id, *val);
kvmppc_set_bescr(vcpu, set_reg_val(id, *val));
break;
case KVM_REG_PPC_IC:
vcpu->arch.ic = set_reg_val(id, *val);
kvmppc_set_ic(vcpu, set_reg_val(id, *val));
break;
default:
r = -EINVAL;
......
......@@ -28,6 +28,7 @@
#include <asm/pte-walk.h>
#include "book3s.h"
#include "book3s_hv.h"
#include "trace_hv.h"
//#define DEBUG_RESIZE_HPT 1
......@@ -120,7 +121,7 @@ void kvmppc_set_hpt(struct kvm *kvm, struct kvm_hpt_info *info)
kvm->arch.hpt = *info;
kvm->arch.sdr1 = __pa(info->virt) | (info->order - 18);
pr_debug("KVM guest htab at %lx (order %ld), LPID %x\n",
pr_debug("KVM guest htab at %lx (order %ld), LPID %llx\n",
info->virt, (long)info->order, kvm->arch.lpid);
}
......@@ -347,7 +348,7 @@ static int kvmppc_mmu_book3s_64_hv_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
unsigned long v, orig_v, gr;
__be64 *hptep;
long int index;
int virtmode = vcpu->arch.shregs.msr & (data ? MSR_DR : MSR_IR);
int virtmode = __kvmppc_get_msr_hv(vcpu) & (data ? MSR_DR : MSR_IR);
if (kvm_is_radix(vcpu->kvm))
return kvmppc_mmu_radix_xlate(vcpu, eaddr, gpte, data, iswrite);
......@@ -385,7 +386,7 @@ static int kvmppc_mmu_book3s_64_hv_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
/* Get PP bits and key for permission check */
pp = gr & (HPTE_R_PP0 | HPTE_R_PP);
key = (vcpu->arch.shregs.msr & MSR_PR) ? SLB_VSID_KP : SLB_VSID_KS;
key = (__kvmppc_get_msr_hv(vcpu) & MSR_PR) ? SLB_VSID_KP : SLB_VSID_KS;
key &= slb_v;
/* Calculate permissions */
......
......@@ -15,6 +15,7 @@
#include <asm/kvm_ppc.h>
#include <asm/kvm_book3s.h>
#include "book3s_hv.h"
#include <asm/page.h>
#include <asm/mmu.h>
#include <asm/pgalloc.h>
......@@ -96,7 +97,7 @@ static long kvmhv_copy_tofrom_guest_radix(struct kvm_vcpu *vcpu, gva_t eaddr,
void *to, void *from, unsigned long n)
{
int lpid = vcpu->kvm->arch.lpid;
int pid = vcpu->arch.pid;
int pid = kvmppc_get_pid(vcpu);
/* This would cause a data segment intr so don't allow the access */
if (eaddr & (0x3FFUL << 52))
......@@ -270,7 +271,7 @@ int kvmppc_mmu_radix_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
/* Work out effective PID */
switch (eaddr >> 62) {
case 0:
pid = vcpu->arch.pid;
pid = kvmppc_get_pid(vcpu);
break;
case 3:
pid = 0;
......@@ -294,9 +295,9 @@ int kvmppc_mmu_radix_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
} else {
if (!(pte & _PAGE_PRIVILEGED)) {
/* Check AMR/IAMR to see if strict mode is in force */
if (vcpu->arch.amr & (1ul << 62))
if (kvmppc_get_amr_hv(vcpu) & (1ul << 62))
gpte->may_read = 0;
if (vcpu->arch.amr & (1ul << 63))
if (kvmppc_get_amr_hv(vcpu) & (1ul << 63))
gpte->may_write = 0;
if (vcpu->arch.iamr & (1ul << 62))
gpte->may_execute = 0;
......@@ -307,7 +308,7 @@ int kvmppc_mmu_radix_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
}
void kvmppc_radix_tlbie_page(struct kvm *kvm, unsigned long addr,
unsigned int pshift, unsigned int lpid)
unsigned int pshift, u64 lpid)
{
unsigned long psize = PAGE_SIZE;
int psi;
......@@ -344,7 +345,7 @@ void kvmppc_radix_tlbie_page(struct kvm *kvm, unsigned long addr,
pr_err("KVM: TLB page invalidation hcall failed, rc=%ld\n", rc);
}
static void kvmppc_radix_flush_pwc(struct kvm *kvm, unsigned int lpid)
static void kvmppc_radix_flush_pwc(struct kvm *kvm, u64 lpid)
{
long rc;
......@@ -417,7 +418,7 @@ static void kvmppc_pmd_free(pmd_t *pmdp)
void kvmppc_unmap_pte(struct kvm *kvm, pte_t *pte, unsigned long gpa,
unsigned int shift,
const struct kvm_memory_slot *memslot,
unsigned int lpid)
u64 lpid)
{
unsigned long old;
......@@ -468,7 +469,7 @@ void kvmppc_unmap_pte(struct kvm *kvm, pte_t *pte, unsigned long gpa,
* (or 4kB) mappings (of sub-pages of the same 2MB page).
*/
static void kvmppc_unmap_free_pte(struct kvm *kvm, pte_t *pte, bool full,
unsigned int lpid)
u64 lpid)
{
if (full) {
memset(pte, 0, sizeof(long) << RADIX_PTE_INDEX_SIZE);
......@@ -489,7 +490,7 @@ static void kvmppc_unmap_free_pte(struct kvm *kvm, pte_t *pte, bool full,
}
static void kvmppc_unmap_free_pmd(struct kvm *kvm, pmd_t *pmd, bool full,
unsigned int lpid)
u64 lpid)
{
unsigned long im;
pmd_t *p = pmd;
......@@ -518,7 +519,7 @@ static void kvmppc_unmap_free_pmd(struct kvm *kvm, pmd_t *pmd, bool full,
}
static void kvmppc_unmap_free_pud(struct kvm *kvm, pud_t *pud,
unsigned int lpid)
u64 lpid)
{
unsigned long iu;
pud_t *p = pud;
......@@ -539,7 +540,7 @@ static void kvmppc_unmap_free_pud(struct kvm *kvm, pud_t *pud,
pud_free(kvm->mm, pud);
}
void kvmppc_free_pgtable_radix(struct kvm *kvm, pgd_t *pgd, unsigned int lpid)
void kvmppc_free_pgtable_radix(struct kvm *kvm, pgd_t *pgd, u64 lpid)
{
unsigned long ig;
......@@ -566,7 +567,7 @@ void kvmppc_free_radix(struct kvm *kvm)
}
static void kvmppc_unmap_free_pmd_entry_table(struct kvm *kvm, pmd_t *pmd,
unsigned long gpa, unsigned int lpid)
unsigned long gpa, u64 lpid)
{
pte_t *pte = pte_offset_kernel(pmd, 0);
......@@ -582,7 +583,7 @@ static void kvmppc_unmap_free_pmd_entry_table(struct kvm *kvm, pmd_t *pmd,
}
static void kvmppc_unmap_free_pud_entry_table(struct kvm *kvm, pud_t *pud,
unsigned long gpa, unsigned int lpid)
unsigned long gpa, u64 lpid)
{
pmd_t *pmd = pmd_offset(pud, 0);
......@@ -608,7 +609,7 @@ static void kvmppc_unmap_free_pud_entry_table(struct kvm *kvm, pud_t *pud,
int kvmppc_create_pte(struct kvm *kvm, pgd_t *pgtable, pte_t pte,
unsigned long gpa, unsigned int level,
unsigned long mmu_seq, unsigned int lpid,
unsigned long mmu_seq, u64 lpid,
unsigned long *rmapp, struct rmap_nested **n_rmap)
{
pgd_t *pgd;
......@@ -785,7 +786,7 @@ int kvmppc_create_pte(struct kvm *kvm, pgd_t *pgtable, pte_t pte,
}
bool kvmppc_hv_handle_set_rc(struct kvm *kvm, bool nested, bool writing,
unsigned long gpa, unsigned int lpid)
unsigned long gpa, u64 lpid)
{
unsigned long pgflags;
unsigned int shift;
......
......@@ -786,12 +786,12 @@ long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
idx = (ioba >> stt->page_shift) - stt->offset;
page = stt->pages[idx / TCES_PER_PAGE];
if (!page) {
vcpu->arch.regs.gpr[4] = 0;
kvmppc_set_gpr(vcpu, 4, 0);
return H_SUCCESS;
}
tbl = (u64 *)page_address(page);
vcpu->arch.regs.gpr[4] = tbl[idx % TCES_PER_PAGE];
kvmppc_set_gpr(vcpu, 4, tbl[idx % TCES_PER_PAGE]);
return H_SUCCESS;
}
......
This diff is collapsed.
......@@ -3,6 +3,8 @@
/*
* Privileged (non-hypervisor) host registers to save.
*/
#include "asm/guest-state-buffer.h"
struct p9_host_os_sprs {
unsigned long iamr;
unsigned long amr;
......@@ -50,3 +52,77 @@ void accumulate_time(struct kvm_vcpu *vcpu, struct kvmhv_tb_accumulator *next);
#define start_timing(vcpu, next) do {} while (0)
#define end_timing(vcpu) do {} while (0)
#endif
static inline void __kvmppc_set_msr_hv(struct kvm_vcpu *vcpu, u64 val)
{
vcpu->arch.shregs.msr = val;
kvmhv_nestedv2_mark_dirty(vcpu, KVMPPC_GSID_MSR);
}
static inline u64 __kvmppc_get_msr_hv(struct kvm_vcpu *vcpu)
{
WARN_ON(kvmhv_nestedv2_cached_reload(vcpu, KVMPPC_GSID_MSR) < 0);
return vcpu->arch.shregs.msr;
}
#define KVMPPC_BOOK3S_HV_VCPU_ACCESSOR_SET(reg, size, iden) \
static inline void kvmppc_set_##reg ##_hv(struct kvm_vcpu *vcpu, u##size val) \
{ \
vcpu->arch.reg = val; \
kvmhv_nestedv2_mark_dirty(vcpu, iden); \
}
#define KVMPPC_BOOK3S_HV_VCPU_ACCESSOR_GET(reg, size, iden) \
static inline u##size kvmppc_get_##reg ##_hv(struct kvm_vcpu *vcpu) \
{ \
kvmhv_nestedv2_cached_reload(vcpu, iden); \
return vcpu->arch.reg; \
}
#define KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(reg, size, iden) \
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR_SET(reg, size, iden) \
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR_GET(reg, size, iden) \
#define KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR_SET(reg, size, iden) \
static inline void kvmppc_set_##reg ##_hv(struct kvm_vcpu *vcpu, int i, u##size val) \
{ \
vcpu->arch.reg[i] = val; \
kvmhv_nestedv2_mark_dirty(vcpu, iden(i)); \
}
#define KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR_GET(reg, size, iden) \
static inline u##size kvmppc_get_##reg ##_hv(struct kvm_vcpu *vcpu, int i) \
{ \
WARN_ON(kvmhv_nestedv2_cached_reload(vcpu, iden(i)) < 0); \
return vcpu->arch.reg[i]; \
}
#define KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR(reg, size, iden) \
KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR_SET(reg, size, iden) \
KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR_GET(reg, size, iden) \
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(mmcra, 64, KVMPPC_GSID_MMCRA)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(hfscr, 64, KVMPPC_GSID_HFSCR)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(fscr, 64, KVMPPC_GSID_FSCR)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dscr, 64, KVMPPC_GSID_DSCR)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(purr, 64, KVMPPC_GSID_PURR)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(spurr, 64, KVMPPC_GSID_SPURR)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(amr, 64, KVMPPC_GSID_AMR)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(uamor, 64, KVMPPC_GSID_UAMOR)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(siar, 64, KVMPPC_GSID_SIAR)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(sdar, 64, KVMPPC_GSID_SDAR)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(iamr, 64, KVMPPC_GSID_IAMR)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dawr0, 64, KVMPPC_GSID_DAWR0)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dawr1, 64, KVMPPC_GSID_DAWR1)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dawrx0, 64, KVMPPC_GSID_DAWRX0)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dawrx1, 64, KVMPPC_GSID_DAWRX1)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(ciabr, 64, KVMPPC_GSID_CIABR)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(wort, 64, KVMPPC_GSID_WORT)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(ppr, 64, KVMPPC_GSID_PPR)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(ctrl, 64, KVMPPC_GSID_CTRL);
KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR(mmcr, 64, KVMPPC_GSID_MMCR)
KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR(sier, 64, KVMPPC_GSID_SIER)
KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR(pmc, 32, KVMPPC_GSID_PMC)
KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(pspb, 32, KVMPPC_GSID_PSPB)
......@@ -32,6 +32,7 @@
#include "book3s_xics.h"
#include "book3s_xive.h"
#include "book3s_hv.h"
/*
* Hash page table alignment on newer cpus(CPU_FTR_ARCH_206)
......@@ -182,9 +183,13 @@ EXPORT_SYMBOL_GPL(kvmppc_hwrng_present);
long kvmppc_rm_h_random(struct kvm_vcpu *vcpu)
{
unsigned long rand;
if (ppc_md.get_random_seed &&
ppc_md.get_random_seed(&vcpu->arch.regs.gpr[4]))
ppc_md.get_random_seed(&rand)) {
kvmppc_set_gpr(vcpu, 4, rand);
return H_SUCCESS;
}
return H_HARDWARE;
}
......@@ -510,7 +515,7 @@ void kvmppc_set_msr_hv(struct kvm_vcpu *vcpu, u64 msr)
*/
if ((msr & MSR_TS_MASK) == MSR_TS_MASK)
msr &= ~MSR_TS_MASK;
vcpu->arch.shregs.msr = msr;
__kvmppc_set_msr_hv(vcpu, msr);
kvmppc_end_cede(vcpu);
}
EXPORT_SYMBOL_GPL(kvmppc_set_msr_hv);
......@@ -548,7 +553,7 @@ static void inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 srr1_flags)
kvmppc_set_srr0(vcpu, pc);
kvmppc_set_srr1(vcpu, (msr & SRR1_MSR_BITS) | srr1_flags);
kvmppc_set_pc(vcpu, new_pc);
vcpu->arch.shregs.msr = new_msr;
__kvmppc_set_msr_hv(vcpu, new_msr);
}
void kvmppc_inject_interrupt_hv(struct kvm_vcpu *vcpu, int vec, u64 srr1_flags)
......
......@@ -428,10 +428,12 @@ long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu)
return vcpu->arch.trap;
}
unsigned long nested_capabilities;
long kvmhv_nested_init(void)
{
long int ptb_order;
unsigned long ptcr;
unsigned long ptcr, host_capabilities;
long rc;
if (!kvmhv_on_pseries())
......@@ -439,6 +441,29 @@ long kvmhv_nested_init(void)
if (!radix_enabled())
return -ENODEV;
rc = plpar_guest_get_capabilities(0, &host_capabilities);
if (rc == H_SUCCESS) {
unsigned long capabilities = 0;
if (cpu_has_feature(CPU_FTR_ARCH_31))
capabilities |= H_GUEST_CAP_POWER10;
if (cpu_has_feature(CPU_FTR_ARCH_300))
capabilities |= H_GUEST_CAP_POWER9;
nested_capabilities = capabilities & host_capabilities;
rc = plpar_guest_set_capabilities(0, nested_capabilities);
if (rc != H_SUCCESS) {
pr_err("kvm-hv: Could not configure parent hypervisor capabilities (rc=%ld)",
rc);
return -ENODEV;
}
static_branch_enable(&__kvmhv_is_nestedv2);
return 0;
}
pr_info("kvm-hv: nestedv2 get capabilities hcall failed, falling back to nestedv1 (rc=%ld)\n",
rc);
/* Partition table entry is 1<<4 bytes in size, hence the 4. */
ptb_order = KVM_MAX_NESTED_GUESTS_SHIFT + 4;
/* Minimum partition table size is 1<<12 bytes */
......@@ -478,7 +503,7 @@ void kvmhv_nested_exit(void)
}
}
static void kvmhv_flush_lpid(unsigned int lpid)
static void kvmhv_flush_lpid(u64 lpid)
{
long rc;
......@@ -500,17 +525,22 @@ static void kvmhv_flush_lpid(unsigned int lpid)
pr_err("KVM: TLB LPID invalidation hcall failed, rc=%ld\n", rc);
}
void kvmhv_set_ptbl_entry(unsigned int lpid, u64 dw0, u64 dw1)
void kvmhv_set_ptbl_entry(u64 lpid, u64 dw0, u64 dw1)
{
if (!kvmhv_on_pseries()) {
mmu_partition_table_set_entry(lpid, dw0, dw1, true);
return;
}
pseries_partition_tb[lpid].patb0 = cpu_to_be64(dw0);
pseries_partition_tb[lpid].patb1 = cpu_to_be64(dw1);
/* L0 will do the necessary barriers */
kvmhv_flush_lpid(lpid);
if (kvmhv_is_nestedv1()) {
pseries_partition_tb[lpid].patb0 = cpu_to_be64(dw0);
pseries_partition_tb[lpid].patb1 = cpu_to_be64(dw1);
/* L0 will do the necessary barriers */
kvmhv_flush_lpid(lpid);
}
if (kvmhv_is_nestedv2())
kvmhv_nestedv2_set_ptbl_entry(lpid, dw0, dw1);
}
static void kvmhv_set_nested_ptbl(struct kvm_nested_guest *gp)
......
This diff is collapsed.
......@@ -305,7 +305,7 @@ static void switch_mmu_to_guest_radix(struct kvm *kvm, struct kvm_vcpu *vcpu, u6
u32 pid;
lpid = nested ? nested->shadow_lpid : kvm->arch.lpid;
pid = vcpu->arch.pid;
pid = kvmppc_get_pid(vcpu);
/*
* Prior memory accesses to host PID Q3 must be completed before we
......@@ -330,7 +330,7 @@ static void switch_mmu_to_guest_hpt(struct kvm *kvm, struct kvm_vcpu *vcpu, u64
int i;
lpid = kvm->arch.lpid;
pid = vcpu->arch.pid;
pid = kvmppc_get_pid(vcpu);
/*
* See switch_mmu_to_guest_radix. ptesync should not be required here
......
......@@ -174,14 +174,14 @@ long kvmppc_p9_realmode_hmi_handler(struct kvm_vcpu *vcpu)
ppc_md.hmi_exception_early(NULL);
out:
if (vc->tb_offset) {
if (kvmppc_get_tb_offset(vcpu)) {
u64 new_tb = mftb() + vc->tb_offset;
mtspr(SPRN_TBU40, new_tb);
if ((mftb() & 0xffffff) < (new_tb & 0xffffff)) {
new_tb += 0x1000000;
mtspr(SPRN_TBU40, new_tb);
}
vc->tb_offset_applied = vc->tb_offset;
vc->tb_offset_applied = kvmppc_get_tb_offset(vcpu);
}
return ret;
......
......@@ -776,8 +776,8 @@ long kvmppc_h_read(struct kvm_vcpu *vcpu, unsigned long flags,
r = rev[i].guest_rpte | (r & (HPTE_R_R | HPTE_R_C));
r &= ~HPTE_GR_RESERVED;
}
vcpu->arch.regs.gpr[4 + i * 2] = v;
vcpu->arch.regs.gpr[5 + i * 2] = r;
kvmppc_set_gpr(vcpu, 4 + i * 2, v);
kvmppc_set_gpr(vcpu, 5 + i * 2, r);
}
return H_SUCCESS;
}
......@@ -824,7 +824,7 @@ long kvmppc_h_clear_ref(struct kvm_vcpu *vcpu, unsigned long flags,
}
}
}
vcpu->arch.regs.gpr[4] = gr;
kvmppc_set_gpr(vcpu, 4, gr);
ret = H_SUCCESS;
out:
unlock_hpte(hpte, v & ~HPTE_V_HVLOCK);
......@@ -872,7 +872,7 @@ long kvmppc_h_clear_mod(struct kvm_vcpu *vcpu, unsigned long flags,
kvmppc_set_dirty_from_hpte(kvm, v, gr);
}
}
vcpu->arch.regs.gpr[4] = gr;
kvmppc_set_gpr(vcpu, 4, gr);
ret = H_SUCCESS;
out:
unlock_hpte(hpte, v & ~HPTE_V_HVLOCK);
......
......@@ -481,7 +481,7 @@ static void icp_rm_down_cppr(struct kvmppc_xics *xics, struct kvmppc_icp *icp,
unsigned long xics_rm_h_xirr_x(struct kvm_vcpu *vcpu)
{
vcpu->arch.regs.gpr[5] = get_tb();
kvmppc_set_gpr(vcpu, 5, get_tb());
return xics_rm_h_xirr(vcpu);
}
......@@ -518,7 +518,7 @@ unsigned long xics_rm_h_xirr(struct kvm_vcpu *vcpu)
} while (!icp_rm_try_update(icp, old_state, new_state));
/* Return the result in GPR4 */
vcpu->arch.regs.gpr[4] = xirr;
kvmppc_set_gpr(vcpu, 4, xirr);
return check_too_hard(xics, icp);
}
......
......@@ -858,7 +858,7 @@ unsigned long kvmppc_h_svm_init_done(struct kvm *kvm)
}
kvm->arch.secure_guest |= KVMPPC_SECURE_INIT_DONE;
pr_info("LPID %d went secure\n", kvm->arch.lpid);
pr_info("LPID %lld went secure\n", kvm->arch.lpid);
out:
srcu_read_unlock(&kvm->srcu, srcu_idx);
......
This diff is collapsed.
......@@ -92,7 +92,8 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
vcpu->arch.mmio_host_swabbed = 0;
emulated = EMULATE_FAIL;
vcpu->arch.regs.msr = vcpu->arch.shared->msr;
vcpu->arch.regs.msr = kvmppc_get_msr(vcpu);
kvmhv_nestedv2_reload_ptregs(vcpu, &vcpu->arch.regs);
if (analyse_instr(&op, &vcpu->arch.regs, inst) == 0) {
int type = op.type & INSTR_TYPE_MASK;
int size = GETSIZE(op.type);
......@@ -250,7 +251,7 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
vcpu->arch.mmio_sp64_extend = 1;
emulated = kvmppc_handle_store(vcpu,
VCPU_FPR(vcpu, op.reg), size, 1);
kvmppc_get_fpr(vcpu, op.reg), size, 1);
if ((op.type & UPDATE) && (emulated != EMULATE_FAIL))
kvmppc_set_gpr(vcpu, op.update_reg, op.ea);
......@@ -357,6 +358,7 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
}
trace_kvm_ppc_instr(ppc_inst_val(inst), kvmppc_get_pc(vcpu), emulated);
kvmhv_nestedv2_mark_dirty_ptregs(vcpu, &vcpu->arch.regs);
/* Advance past emulated instruction. */
if (emulated != EMULATE_FAIL)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment