Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 167c76e0 authored by Paul Mackerras's avatar Paul Mackerras
Browse files

Merge remote-tracking branch 'remotes/powerpc/topic/ppc-kvm' into kvm-ppc-next



This merges in the POWER9 radix MMU host and guest support, which
was put into a topic branch because it touches both powerpc and
KVM code.

Signed-off-by: default avatarPaul Mackerras <paulus@ozlabs.org>
parents fcd4f3c6 8cf4ecc0
Loading
Loading
Loading
Loading
+83 −0
Original line number Diff line number Diff line
@@ -3201,6 +3201,71 @@ struct kvm_reinject_control {
pit_reinject = 0 (!reinject mode) is recommended, unless running an old
operating system that uses the PIT for timing (e.g. Linux 2.4.x).

4.99 KVM_PPC_CONFIGURE_V3_MMU

Capability: KVM_CAP_PPC_RADIX_MMU or KVM_CAP_PPC_HASH_MMU_V3
Architectures: ppc
Type: vm ioctl
Parameters: struct kvm_ppc_mmuv3_cfg (in)
Returns: 0 on success,
         -EFAULT if struct kvm_ppc_mmuv3_cfg cannot be read,
         -EINVAL if the configuration is invalid

This ioctl controls whether the guest will use radix or HPT (hashed
page table) translation, and sets the pointer to the process table for
the guest.

struct kvm_ppc_mmuv3_cfg {
	__u64	flags;
	__u64	process_table;
};

There are two bits that can be set in flags; KVM_PPC_MMUV3_RADIX and
KVM_PPC_MMUV3_GTSE.  KVM_PPC_MMUV3_RADIX, if set, configures the guest
to use radix tree translation, and if clear, to use HPT translation.
KVM_PPC_MMUV3_GTSE, if set and if KVM permits it, configures the guest
to be able to use the global TLB and SLB invalidation instructions;
if clear, the guest may not use these instructions.

The process_table field specifies the address and size of the guest
process table, which is in the guest's space.  This field is formatted
as the second doubleword of the partition table entry, as defined in
the Power ISA V3.00, Book III section 5.7.6.1.

4.100 KVM_PPC_GET_RMMU_INFO

Capability: KVM_CAP_PPC_RADIX_MMU
Architectures: ppc
Type: vm ioctl
Parameters: struct kvm_ppc_rmmu_info (out)
Returns: 0 on success,
	 -EFAULT if struct kvm_ppc_rmmu_info cannot be written,
	 -EINVAL if no useful information can be returned

This ioctl returns a structure containing two things: (a) a list
containing supported radix tree geometries, and (b) a list that maps
page sizes to put in the "AP" (actual page size) field for the tlbie
(TLB invalidate entry) instruction.

struct kvm_ppc_rmmu_info {
	struct kvm_ppc_radix_geom {
		__u8	page_shift;
		__u8	level_bits[4];
		__u8	pad[3];
	}	geometries[8];
	__u32	ap_encodings[8];
};

The geometries[] field gives up to 8 supported geometries for the
radix page table, in terms of the log base 2 of the smallest page
size, and the number of bits indexed at each level of the tree, from
the PTE level up to the PGD level in that order.  Any unused entries
will have 0 in the page_shift field.

The ap_encodings gives the supported page sizes and their AP field
encodings, encoded with the AP value in the top 3 bits and the log
base 2 of the page size in the bottom 6 bits.

5. The kvm_run structure
------------------------

@@ -3942,3 +4007,21 @@ In order to use SynIC, it has to be activated by setting this
capability via KVM_ENABLE_CAP ioctl on the vcpu fd. Note that this
will disable the use of APIC hardware virtualization even if supported
by the CPU, as it's incompatible with SynIC auto-EOI behavior.

8.3 KVM_CAP_PPC_RADIX_MMU

Architectures: ppc

This capability, if KVM_CHECK_EXTENSION indicates that it is
available, means that that the kernel can support guests using the
radix MMU defined in Power ISA V3.00 (as implemented in the POWER9
processor).

8.4 KVM_CAP_PPC_HASH_MMU_V3

Architectures: ppc

This capability, if KVM_CHECK_EXTENSION indicates that it is
available, means that that the kernel can support guests using the
hashed page table MMU defined in Power ISA V3.00 (as implemented in
the POWER9 processor), including in-memory segment tables.
+17 −1
Original line number Diff line number Diff line
@@ -44,10 +44,20 @@ struct patb_entry {
};
extern struct patb_entry *partition_tb;

/* Bits in patb0 field */
#define PATB_HR		(1UL << 63)
#define PATB_GR		(1UL << 63)
#define RPDB_MASK	0x0ffffffffffff00fUL
#define RPDB_SHIFT	(1UL << 8)
#define RTS1_SHIFT	61		/* top 2 bits of radix tree size */
#define RTS1_MASK	(3UL << RTS1_SHIFT)
#define RTS2_SHIFT	5		/* bottom 3 bits of radix tree size */
#define RTS2_MASK	(7UL << RTS2_SHIFT)
#define RPDS_MASK	0x1f		/* root page dir. size field */

/* Bits in patb1 field */
#define PATB_GR		(1UL << 63)	/* guest uses radix; must match HR */
#define PRTS_MASK	0x1f		/* process table size field */

/*
 * Limit process table to PAGE_SIZE table. This
 * also limit the max pid we can support.
@@ -138,5 +148,11 @@ static inline void setup_initial_memory_limit(phys_addr_t first_memblock_base,
extern int (*register_process_table)(unsigned long base, unsigned long page_size,
				     unsigned long tbl_size);

#ifdef CONFIG_PPC_PSERIES
extern void radix_init_pseries(void);
#else
static inline void radix_init_pseries(void) { };
#endif

#endif /* __ASSEMBLY__ */
#endif /* _ASM_POWERPC_BOOK3S_64_MMU_H_ */
+55 −20
Original line number Diff line number Diff line
@@ -97,6 +97,15 @@
	ld	reg,PACAKBASE(r13);					\
	ori	reg,reg,(ABS_ADDR(label))@l;

/*
 * Branches from unrelocated code (e.g., interrupts) to labels outside
 * head-y require >64K offsets.
 */
#define __LOAD_FAR_HANDLER(reg, label)					\
	ld	reg,PACAKBASE(r13);					\
	ori	reg,reg,(ABS_ADDR(label))@l;				\
	addis	reg,reg,(ABS_ADDR(label))@h;

/* Exception register prefixes */
#define EXC_HV	H
#define EXC_STD
@@ -227,13 +236,41 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
	mtctr	reg;							\
	bctr

/*
 * KVM requires __LOAD_FAR_HANDLER.
 *
 * __BRANCH_TO_KVM_EXIT branches are also a special case because they
 * explicitly use r9 then reload it from PACA before branching. Hence
 * the double-underscore.
 */
#define __BRANCH_TO_KVM_EXIT(area, label)				\
	mfctr	r9;							\
	std	r9,HSTATE_SCRATCH1(r13);				\
	__LOAD_FAR_HANDLER(r9, label);					\
	mtctr	r9;							\
	ld	r9,area+EX_R9(r13);					\
	bctr

#define BRANCH_TO_KVM(reg, label)					\
	__LOAD_FAR_HANDLER(reg, label);					\
	mtctr	reg;							\
	bctr

#else
#define BRANCH_TO_COMMON(reg, label)					\
	b	label

#define BRANCH_TO_KVM(reg, label)					\
	b	label

#define __BRANCH_TO_KVM_EXIT(area, label)				\
	ld	r9,area+EX_R9(r13);					\
	b	label

#endif

#define __KVM_HANDLER_PROLOG(area, n)					\

#define __KVM_HANDLER(area, h, n)					\
	BEGIN_FTR_SECTION_NESTED(947)					\
	ld	r10,area+EX_CFAR(r13);					\
	std	r10,HSTATE_CFAR(r13);					\
@@ -243,30 +280,28 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
	std	r10,HSTATE_PPR(r13);					\
	END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948);	\
	ld	r10,area+EX_R10(r13);					\
	stw	r9,HSTATE_SCRATCH1(r13);				\
	ld	r9,area+EX_R9(r13);					\
	std	r12,HSTATE_SCRATCH0(r13);				\

#define __KVM_HANDLER(area, h, n)					\
	__KVM_HANDLER_PROLOG(area, n)					\
	li	r12,n;							\
	b	kvmppc_interrupt
	sldi	r12,r9,32;						\
	ori	r12,r12,(n);						\
	/* This reloads r9 before branching to kvmppc_interrupt */	\
	__BRANCH_TO_KVM_EXIT(area, kvmppc_interrupt)

#define __KVM_HANDLER_SKIP(area, h, n)					\
	cmpwi	r10,KVM_GUEST_MODE_SKIP;				\
	ld	r10,area+EX_R10(r13);					\
	beq	89f;							\
	stw	r9,HSTATE_SCRATCH1(r13);				\
	BEGIN_FTR_SECTION_NESTED(948)					\
	ld	r9,area+EX_PPR(r13);					\
	std	r9,HSTATE_PPR(r13);					\
	ld	r10,area+EX_PPR(r13);					\
	std	r10,HSTATE_PPR(r13);					\
	END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948);	\
	ld	r9,area+EX_R9(r13);					\
	ld	r10,area+EX_R10(r13);					\
	std	r12,HSTATE_SCRATCH0(r13);				\
	li	r12,n;							\
	b	kvmppc_interrupt;					\
	sldi	r12,r9,32;						\
	ori	r12,r12,(n);						\
	/* This reloads r9 before branching to kvmppc_interrupt */	\
	__BRANCH_TO_KVM_EXIT(area, kvmppc_interrupt);			\
89:	mtocrf	0x80,r9;						\
	ld	r9,area+EX_R9(r13);					\
	ld	r10,area+EX_R10(r13);					\
	b	kvmppc_skip_##h##interrupt

#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
@@ -393,12 +428,12 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
	EXCEPTION_RELON_PROLOG_PSERIES_1(label, EXC_STD)

#define STD_RELON_EXCEPTION_HV(loc, vec, label)		\
	/* No guest interrupts come through here */	\
	SET_SCRATCH0(r13);	/* save r13 */		\
	EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label, EXC_HV, NOTEST, vec);
	EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label,	\
				       EXC_HV, KVMTEST_HV, vec);

#define STD_RELON_EXCEPTION_HV_OOL(vec, label)			\
	EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, vec);		\
	EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_HV, vec);	\
	EXCEPTION_RELON_PROLOG_PSERIES_1(label, EXC_HV)

/* This associate vector numbers with bits in paca->irq_happened */
@@ -475,10 +510,10 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)

#define MASKABLE_RELON_EXCEPTION_HV(loc, vec, label)			\
	_MASKABLE_RELON_EXCEPTION_PSERIES(vec, label,			\
					  EXC_HV, SOFTEN_NOTEST_HV)
					  EXC_HV, SOFTEN_TEST_HV)

#define MASKABLE_RELON_EXCEPTION_HV_OOL(vec, label)			\
	EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_NOTEST_HV, vec);		\
	EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_HV, vec);		\
	EXCEPTION_PROLOG_PSERIES_1(label, EXC_HV)

/*
+1 −1
Original line number Diff line number Diff line
@@ -218,7 +218,7 @@ end_##sname:

#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
#define TRAMP_KVM_BEGIN(name)						\
	TRAMP_REAL_BEGIN(name)
	TRAMP_VIRT_BEGIN(name)
#else
#define TRAMP_KVM_BEGIN(name)
#endif
+11 −0
Original line number Diff line number Diff line
@@ -276,6 +276,7 @@
#define H_GET_MPP_X		0x314
#define H_SET_MODE		0x31C
#define H_CLEAR_HPT		0x358
#define H_REGISTER_PROC_TBL	0x37C
#define H_SIGNAL_SYS_RESET	0x380
#define MAX_HCALL_OPCODE	H_SIGNAL_SYS_RESET

@@ -313,6 +314,16 @@
#define H_SIGNAL_SYS_RESET_ALL_OTHERS		-2
/* >= 0 values are CPU number */

/* Flag values used in H_REGISTER_PROC_TBL hcall */
#define PROC_TABLE_OP_MASK	0x18
#define PROC_TABLE_DEREG	0x10
#define PROC_TABLE_NEW		0x18
#define PROC_TABLE_TYPE_MASK	0x06
#define PROC_TABLE_HPT_SLB	0x00
#define PROC_TABLE_HPT_PT	0x02
#define PROC_TABLE_RADIX	0x04
#define PROC_TABLE_GTSE		0x01

#ifndef __ASSEMBLY__

/**
Loading