cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

e500.h (8818B)


      1/* SPDX-License-Identifier: GPL-2.0-only */
      2/*
      3 * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved.
      4 *
      5 * Author: Yu Liu <yu.liu@freescale.com>
      6 *         Scott Wood <scottwood@freescale.com>
      7 *         Ashish Kalra <ashish.kalra@freescale.com>
      8 *         Varun Sethi <varun.sethi@freescale.com>
      9 *
     10 * Description:
     11 * This file is based on arch/powerpc/kvm/44x_tlb.h and
     12 * arch/powerpc/include/asm/kvm_44x.h by Hollis Blanchard <hollisb@us.ibm.com>,
     13 * Copyright IBM Corp. 2007-2008
     14 */
     15
     16#ifndef KVM_E500_H
     17#define KVM_E500_H
     18
     19#include <linux/kvm_host.h>
     20#include <asm/nohash/mmu-book3e.h>
     21#include <asm/tlb.h>
     22#include <asm/cputhreads.h>
     23
     24enum vcpu_ftr {
     25	VCPU_FTR_MMU_V2
     26};
     27
     28#define E500_PID_NUM   3
     29#define E500_TLB_NUM   2
     30
     31/* entry is mapped somewhere in host TLB */
     32#define E500_TLB_VALID		(1 << 31)
     33/* TLB1 entry is mapped by host TLB1, tracked by bitmaps */
     34#define E500_TLB_BITMAP		(1 << 30)
     35/* TLB1 entry is mapped by host TLB0 */
     36#define E500_TLB_TLB0		(1 << 29)
     37/* bits [6-5] MAS2_X1 and MAS2_X0 and [4-0] bits for WIMGE */
     38#define E500_TLB_MAS2_ATTR	(0x7f)
     39
     40struct tlbe_ref {
     41	kvm_pfn_t pfn;		/* valid only for TLB0, except briefly */
     42	unsigned int flags;	/* E500_TLB_* */
     43};
     44
     45struct tlbe_priv {
     46	struct tlbe_ref ref;
     47};
     48
     49#ifdef CONFIG_KVM_E500V2
     50struct vcpu_id_table;
     51#endif
     52
     53struct kvmppc_e500_tlb_params {
     54	int entries, ways, sets;
     55};
     56
     57struct kvmppc_vcpu_e500 {
     58	struct kvm_vcpu vcpu;
     59
     60	/* Unmodified copy of the guest's TLB -- shared with host userspace. */
     61	struct kvm_book3e_206_tlb_entry *gtlb_arch;
     62
     63	/* Starting entry number in gtlb_arch[] */
     64	int gtlb_offset[E500_TLB_NUM];
     65
     66	/* KVM internal information associated with each guest TLB entry */
     67	struct tlbe_priv *gtlb_priv[E500_TLB_NUM];
     68
     69	struct kvmppc_e500_tlb_params gtlb_params[E500_TLB_NUM];
     70
     71	unsigned int gtlb_nv[E500_TLB_NUM];
     72
     73	unsigned int host_tlb1_nv;
     74
     75	u32 svr;
     76	u32 l1csr0;
     77	u32 l1csr1;
     78	u32 hid0;
     79	u32 hid1;
     80	u64 mcar;
     81
     82	struct page **shared_tlb_pages;
     83	int num_shared_tlb_pages;
     84
     85	u64 *g2h_tlb1_map;
     86	unsigned int *h2g_tlb1_rmap;
     87
     88	/* Minimum and maximum address mapped my TLB1 */
     89	unsigned long tlb1_min_eaddr;
     90	unsigned long tlb1_max_eaddr;
     91
     92#ifdef CONFIG_KVM_E500V2
     93	u32 pid[E500_PID_NUM];
     94
     95	/* vcpu id table */
     96	struct vcpu_id_table *idt;
     97#endif
     98};
     99
    100static inline struct kvmppc_vcpu_e500 *to_e500(struct kvm_vcpu *vcpu)
    101{
    102	return container_of(vcpu, struct kvmppc_vcpu_e500, vcpu);
    103}
    104
    105
    106/* This geometry is the legacy default -- can be overridden by userspace */
    107#define KVM_E500_TLB0_WAY_SIZE		128
    108#define KVM_E500_TLB0_WAY_NUM		2
    109
    110#define KVM_E500_TLB0_SIZE  (KVM_E500_TLB0_WAY_SIZE * KVM_E500_TLB0_WAY_NUM)
    111#define KVM_E500_TLB1_SIZE  16
    112
    113#define index_of(tlbsel, esel)	(((tlbsel) << 16) | ((esel) & 0xFFFF))
    114#define tlbsel_of(index)	((index) >> 16)
    115#define esel_of(index)		((index) & 0xFFFF)
    116
    117#define E500_TLB_USER_PERM_MASK (MAS3_UX|MAS3_UR|MAS3_UW)
    118#define E500_TLB_SUPER_PERM_MASK (MAS3_SX|MAS3_SR|MAS3_SW)
    119#define MAS2_ATTRIB_MASK \
    120	  (MAS2_X0 | MAS2_X1 | MAS2_E | MAS2_G)
    121#define MAS3_ATTRIB_MASK \
    122	  (MAS3_U0 | MAS3_U1 | MAS3_U2 | MAS3_U3 \
    123	   | E500_TLB_USER_PERM_MASK | E500_TLB_SUPER_PERM_MASK)
    124
    125int kvmppc_e500_emul_mt_mmucsr0(struct kvmppc_vcpu_e500 *vcpu_e500,
    126				ulong value);
    127int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu);
    128int kvmppc_e500_emul_tlbre(struct kvm_vcpu *vcpu);
    129int kvmppc_e500_emul_tlbivax(struct kvm_vcpu *vcpu, gva_t ea);
    130int kvmppc_e500_emul_tlbilx(struct kvm_vcpu *vcpu, int type, gva_t ea);
    131int kvmppc_e500_emul_tlbsx(struct kvm_vcpu *vcpu, gva_t ea);
    132int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500);
    133void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *vcpu_e500);
    134
    135void kvmppc_get_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
    136int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
    137
    138int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
    139				union kvmppc_one_reg *val);
    140int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
    141			       union kvmppc_one_reg *val);
    142
    143#ifdef CONFIG_KVM_E500V2
    144unsigned int kvmppc_e500_get_sid(struct kvmppc_vcpu_e500 *vcpu_e500,
    145				 unsigned int as, unsigned int gid,
    146				 unsigned int pr, int avoid_recursion);
    147#endif
    148
    149/* TLB helper functions */
    150static inline unsigned int
    151get_tlb_size(const struct kvm_book3e_206_tlb_entry *tlbe)
    152{
    153	return (tlbe->mas1 >> 7) & 0x1f;
    154}
    155
    156static inline gva_t get_tlb_eaddr(const struct kvm_book3e_206_tlb_entry *tlbe)
    157{
    158	return tlbe->mas2 & MAS2_EPN;
    159}
    160
    161static inline u64 get_tlb_bytes(const struct kvm_book3e_206_tlb_entry *tlbe)
    162{
    163	unsigned int pgsize = get_tlb_size(tlbe);
    164	return 1ULL << 10 << pgsize;
    165}
    166
    167static inline gva_t get_tlb_end(const struct kvm_book3e_206_tlb_entry *tlbe)
    168{
    169	u64 bytes = get_tlb_bytes(tlbe);
    170	return get_tlb_eaddr(tlbe) + bytes - 1;
    171}
    172
    173static inline u64 get_tlb_raddr(const struct kvm_book3e_206_tlb_entry *tlbe)
    174{
    175	return tlbe->mas7_3 & ~0xfffULL;
    176}
    177
    178static inline unsigned int
    179get_tlb_tid(const struct kvm_book3e_206_tlb_entry *tlbe)
    180{
    181	return (tlbe->mas1 >> 16) & 0xff;
    182}
    183
    184static inline unsigned int
    185get_tlb_ts(const struct kvm_book3e_206_tlb_entry *tlbe)
    186{
    187	return (tlbe->mas1 >> 12) & 0x1;
    188}
    189
    190static inline unsigned int
    191get_tlb_v(const struct kvm_book3e_206_tlb_entry *tlbe)
    192{
    193	return (tlbe->mas1 >> 31) & 0x1;
    194}
    195
    196static inline unsigned int
    197get_tlb_iprot(const struct kvm_book3e_206_tlb_entry *tlbe)
    198{
    199	return (tlbe->mas1 >> 30) & 0x1;
    200}
    201
    202static inline unsigned int
    203get_tlb_tsize(const struct kvm_book3e_206_tlb_entry *tlbe)
    204{
    205	return (tlbe->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
    206}
    207
    208static inline unsigned int get_cur_pid(struct kvm_vcpu *vcpu)
    209{
    210	return vcpu->arch.pid & 0xff;
    211}
    212
    213static inline unsigned int get_cur_as(struct kvm_vcpu *vcpu)
    214{
    215	return !!(vcpu->arch.shared->msr & (MSR_IS | MSR_DS));
    216}
    217
    218static inline unsigned int get_cur_pr(struct kvm_vcpu *vcpu)
    219{
    220	return !!(vcpu->arch.shared->msr & MSR_PR);
    221}
    222
    223static inline unsigned int get_cur_spid(const struct kvm_vcpu *vcpu)
    224{
    225	return (vcpu->arch.shared->mas6 >> 16) & 0xff;
    226}
    227
    228static inline unsigned int get_cur_sas(const struct kvm_vcpu *vcpu)
    229{
    230	return vcpu->arch.shared->mas6 & 0x1;
    231}
    232
    233static inline unsigned int get_tlb_tlbsel(const struct kvm_vcpu *vcpu)
    234{
    235	/*
    236	 * Manual says that tlbsel has 2 bits wide.
    237	 * Since we only have two TLBs, only lower bit is used.
    238	 */
    239	return (vcpu->arch.shared->mas0 >> 28) & 0x1;
    240}
    241
    242static inline unsigned int get_tlb_nv_bit(const struct kvm_vcpu *vcpu)
    243{
    244	return vcpu->arch.shared->mas0 & 0xfff;
    245}
    246
    247static inline unsigned int get_tlb_esel_bit(const struct kvm_vcpu *vcpu)
    248{
    249	return (vcpu->arch.shared->mas0 >> 16) & 0xfff;
    250}
    251
    252static inline int tlbe_is_host_safe(const struct kvm_vcpu *vcpu,
    253			const struct kvm_book3e_206_tlb_entry *tlbe)
    254{
    255	gpa_t gpa;
    256
    257	if (!get_tlb_v(tlbe))
    258		return 0;
    259
    260#ifndef CONFIG_KVM_BOOKE_HV
    261	/* Does it match current guest AS? */
    262	/* XXX what about IS != DS? */
    263	if (get_tlb_ts(tlbe) != !!(vcpu->arch.shared->msr & MSR_IS))
    264		return 0;
    265#endif
    266
    267	gpa = get_tlb_raddr(tlbe);
    268	if (!gfn_to_memslot(vcpu->kvm, gpa >> PAGE_SHIFT))
    269		/* Mapping is not for RAM. */
    270		return 0;
    271
    272	return 1;
    273}
    274
    275static inline struct kvm_book3e_206_tlb_entry *get_entry(
    276	struct kvmppc_vcpu_e500 *vcpu_e500, int tlbsel, int entry)
    277{
    278	int offset = vcpu_e500->gtlb_offset[tlbsel];
    279	return &vcpu_e500->gtlb_arch[offset + entry];
    280}
    281
    282void kvmppc_e500_tlbil_one(struct kvmppc_vcpu_e500 *vcpu_e500,
    283			   struct kvm_book3e_206_tlb_entry *gtlbe);
    284void kvmppc_e500_tlbil_all(struct kvmppc_vcpu_e500 *vcpu_e500);
    285
    286#ifdef CONFIG_KVM_BOOKE_HV
    287#define kvmppc_e500_get_tlb_stid(vcpu, gtlbe)       get_tlb_tid(gtlbe)
    288#define get_tlbmiss_tid(vcpu)           get_cur_pid(vcpu)
    289#define get_tlb_sts(gtlbe)              (gtlbe->mas1 & MAS1_TS)
    290
    291/*
    292 * These functions should be called with preemption disabled
    293 * and the returned value is valid only in that context
    294 */
    295static inline int get_thread_specific_lpid(int vm_lpid)
    296{
    297	int vcpu_lpid = vm_lpid;
    298
    299	if (threads_per_core == 2)
    300		vcpu_lpid |= smp_processor_id() & 1;
    301
    302	return vcpu_lpid;
    303}
    304
    305static inline int get_lpid(struct kvm_vcpu *vcpu)
    306{
    307	return get_thread_specific_lpid(vcpu->kvm->arch.lpid);
    308}
    309#else
    310unsigned int kvmppc_e500_get_tlb_stid(struct kvm_vcpu *vcpu,
    311				      struct kvm_book3e_206_tlb_entry *gtlbe);
    312
    313static inline unsigned int get_tlbmiss_tid(struct kvm_vcpu *vcpu)
    314{
    315	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
    316	unsigned int tidseld = (vcpu->arch.shared->mas4 >> 16) & 0xf;
    317
    318	return vcpu_e500->pid[tidseld];
    319}
    320
    321/* Force TS=1 for all guest mappings. */
    322#define get_tlb_sts(gtlbe)              (MAS1_TS)
    323#endif /* !BOOKE_HV */
    324
    325static inline bool has_feature(const struct kvm_vcpu *vcpu,
    326			       enum vcpu_ftr ftr)
    327{
    328	bool has_ftr;
    329	switch (ftr) {
    330	case VCPU_FTR_MMU_V2:
    331		has_ftr = ((vcpu->arch.mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V2);
    332		break;
    333	default:
    334		return false;
    335	}
    336	return has_ftr;
    337}
    338
    339#endif /* KVM_E500_H */