Commit 7dd2157c authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge tag 'kvm-ppc-next-4.20-1' of...

Merge tag 'kvm-ppc-next-4.20-1' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc into HEAD

PPC KVM update for 4.20.

The major new feature here is nested HV KVM support.  This allows the
HV KVM module to load inside a radix guest on POWER9 and run radix
guests underneath it.  These nested guests can run in supervisor mode
and don't require any additional instructions to be emulated, unlike
with PR KVM, and so performance is much better than with PR KVM, and
is very close to the performance of a non-nested guest.  A nested
hypervisor (a guest with nested guests) can be migrated to another
host and will bring all its nested guests along with it.  A nested
guest can also itself run guests, and so on down to any desired depth
of nesting.

Apart from that there are a series of updates for IOMMU handling from
Alexey Kardashevskiy, a "one VM per core" mode for HV KVM for
security-paranoid applications, and a small fix for PR KVM.
parents dd5bd0a6 901f8c3f
Loading
Loading
Loading
Loading
+19 −0
Original line number Original line Diff line number Diff line
@@ -1922,6 +1922,7 @@ registers, find a list below:
  PPC   | KVM_REG_PPC_TIDR              | 64
  PPC   | KVM_REG_PPC_TIDR              | 64
  PPC   | KVM_REG_PPC_PSSCR             | 64
  PPC   | KVM_REG_PPC_PSSCR             | 64
  PPC   | KVM_REG_PPC_DEC_EXPIRY        | 64
  PPC   | KVM_REG_PPC_DEC_EXPIRY        | 64
  PPC   | KVM_REG_PPC_PTCR              | 64
  PPC   | KVM_REG_PPC_TM_GPR0           | 64
  PPC   | KVM_REG_PPC_TM_GPR0           | 64
          ...
          ...
  PPC   | KVM_REG_PPC_TM_GPR31          | 64
  PPC   | KVM_REG_PPC_TM_GPR31          | 64
@@ -2269,6 +2270,10 @@ The supported flags are:
        The emulated MMU supports 1T segments in addition to the
        The emulated MMU supports 1T segments in addition to the
        standard 256M ones.
        standard 256M ones.


    - KVM_PPC_NO_HASH
	This flag indicates that HPT guests are not supported by KVM,
	thus all guests must use radix MMU mode.

The "slb_size" field indicates how many SLB entries are supported
The "slb_size" field indicates how many SLB entries are supported


The "sps" array contains 8 entries indicating the supported base
The "sps" array contains 8 entries indicating the supported base
@@ -4531,6 +4536,20 @@ With this capability, a guest may read the MSR_PLATFORM_INFO MSR. Otherwise,
a #GP would be raised when the guest tries to access. Currently, this
a #GP would be raised when the guest tries to access. Currently, this
capability does not enable write permissions of this MSR for the guest.
capability does not enable write permissions of this MSR for the guest.


7.16 KVM_CAP_PPC_NESTED_HV

Architectures: ppc
Parameters: none
Returns: 0 on success, -EINVAL when the implementation doesn't support
	 nested-HV virtualization.

HV-KVM on POWER9 and later systems allows for "nested-HV"
virtualization, which provides a way for a guest VM to run guests that
can run using the CPU's supervisor mode (privileged non-hypervisor
state).  Enabling this capability on a VM depends on the CPU having
the necessary functionality and on the facility being enabled with a
kvm-hv module parameter.

8. Other capabilities.
8. Other capabilities.
----------------------
----------------------


+21 −0
Original line number Original line Diff line number Diff line
@@ -150,4 +150,25 @@ extern s32 patch__memset_nocache, patch__memcpy_nocache;


extern long flush_count_cache;
extern long flush_count_cache;


#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
void kvmppc_save_tm_hv(struct kvm_vcpu *vcpu, u64 msr, bool preserve_nv);
void kvmppc_restore_tm_hv(struct kvm_vcpu *vcpu, u64 msr, bool preserve_nv);
#else
static inline void kvmppc_save_tm_hv(struct kvm_vcpu *vcpu, u64 msr,
				     bool preserve_nv) { }
static inline void kvmppc_restore_tm_hv(struct kvm_vcpu *vcpu, u64 msr,
					bool preserve_nv) { }
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */

void kvmhv_save_host_pmu(void);
void kvmhv_load_host_pmu(void);
void kvmhv_save_guest_pmu(struct kvm_vcpu *vcpu, bool pmu_in_use);
void kvmhv_load_guest_pmu(struct kvm_vcpu *vcpu);

int __kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu);

long kvmppc_h_set_dabr(struct kvm_vcpu *vcpu, unsigned long dabr);
long kvmppc_h_set_xdabr(struct kvm_vcpu *vcpu, unsigned long dabr,
			unsigned long dabrx);

#endif /* _ASM_POWERPC_ASM_PROTOTYPES_H */
#endif /* _ASM_POWERPC_ASM_PROTOTYPES_H */
+12 −0
Original line number Original line Diff line number Diff line
@@ -203,6 +203,18 @@ static inline unsigned int mmu_psize_to_shift(unsigned int mmu_psize)
	BUG();
	BUG();
}
}


static inline unsigned int ap_to_shift(unsigned long ap)
{
	int psize;

	for (psize = 0; psize < MMU_PAGE_COUNT; psize++) {
		if (mmu_psize_defs[psize].ap == ap)
			return mmu_psize_defs[psize].shift;
	}

	return -1;
}

static inline unsigned long get_sllp_encoding(int psize)
static inline unsigned long get_sllp_encoding(int psize)
{
{
	unsigned long sllp;
	unsigned long sllp;
+1 −0
Original line number Original line Diff line number Diff line
@@ -53,6 +53,7 @@ extern void radix__flush_tlb_lpid_page(unsigned int lpid,
					unsigned long addr,
					unsigned long addr,
					unsigned long page_size);
					unsigned long page_size);
extern void radix__flush_pwc_lpid(unsigned int lpid);
extern void radix__flush_pwc_lpid(unsigned int lpid);
extern void radix__flush_tlb_lpid(unsigned int lpid);
extern void radix__local_flush_tlb_lpid(unsigned int lpid);
extern void radix__local_flush_tlb_lpid(unsigned int lpid);
extern void radix__local_flush_tlb_lpid_guest(unsigned int lpid);
extern void radix__local_flush_tlb_lpid_guest(unsigned int lpid);


+41 −0
Original line number Original line Diff line number Diff line
@@ -322,6 +322,11 @@
#define H_GET_24X7_DATA		0xF07C
#define H_GET_24X7_DATA		0xF07C
#define H_GET_PERF_COUNTER_INFO	0xF080
#define H_GET_PERF_COUNTER_INFO	0xF080


/* Platform-specific hcalls used for nested HV KVM */
#define H_SET_PARTITION_TABLE	0xF800
#define H_ENTER_NESTED		0xF804
#define H_TLB_INVALIDATE	0xF808

/* Values for 2nd argument to H_SET_MODE */
/* Values for 2nd argument to H_SET_MODE */
#define H_SET_MODE_RESOURCE_SET_CIABR		1
#define H_SET_MODE_RESOURCE_SET_CIABR		1
#define H_SET_MODE_RESOURCE_SET_DAWR		2
#define H_SET_MODE_RESOURCE_SET_DAWR		2
@@ -461,6 +466,42 @@ struct h_cpu_char_result {
	u64 behaviour;
	u64 behaviour;
};
};


/* Register state for entering a nested guest with H_ENTER_NESTED */
struct hv_guest_state {
	u64 version;		/* version of this structure layout */
	u32 lpid;
	u32 vcpu_token;
	/* These registers are hypervisor privileged (at least for writing) */
	u64 lpcr;
	u64 pcr;
	u64 amor;
	u64 dpdes;
	u64 hfscr;
	s64 tb_offset;
	u64 dawr0;
	u64 dawrx0;
	u64 ciabr;
	u64 hdec_expiry;
	u64 purr;
	u64 spurr;
	u64 ic;
	u64 vtb;
	u64 hdar;
	u64 hdsisr;
	u64 heir;
	u64 asdr;
	/* These are OS privileged but need to be set late in guest entry */
	u64 srr0;
	u64 srr1;
	u64 sprg[4];
	u64 pidr;
	u64 cfar;
	u64 ppr;
};

/* Latest version of hv_guest_state structure */
#define HV_GUEST_STATE_VERSION	1

#endif /* __ASSEMBLY__ */
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_HVCALL_H */
#endif /* _ASM_POWERPC_HVCALL_H */
Loading