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

e500mc.c (10546B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2010,2012 Freescale Semiconductor, Inc. All rights reserved.
      4 *
      5 * Author: Varun Sethi, <varun.sethi@freescale.com>
      6 *
      7 * Description:
      8 * This file is derived from arch/powerpc/kvm/e500.c,
      9 * by Yu Liu <yu.liu@freescale.com>.
     10 */
     11
     12#include <linux/kvm_host.h>
     13#include <linux/slab.h>
     14#include <linux/err.h>
     15#include <linux/export.h>
     16#include <linux/miscdevice.h>
     17#include <linux/module.h>
     18
     19#include <asm/reg.h>
     20#include <asm/cputable.h>
     21#include <asm/kvm_ppc.h>
     22#include <asm/dbell.h>
     23
     24#include "booke.h"
     25#include "e500.h"
     26
     27void kvmppc_set_pending_interrupt(struct kvm_vcpu *vcpu, enum int_class type)
     28{
     29	enum ppc_dbell dbell_type;
     30	unsigned long tag;
     31
     32	switch (type) {
     33	case INT_CLASS_NONCRIT:
     34		dbell_type = PPC_G_DBELL;
     35		break;
     36	case INT_CLASS_CRIT:
     37		dbell_type = PPC_G_DBELL_CRIT;
     38		break;
     39	case INT_CLASS_MC:
     40		dbell_type = PPC_G_DBELL_MC;
     41		break;
     42	default:
     43		WARN_ONCE(1, "%s: unknown int type %d\n", __func__, type);
     44		return;
     45	}
     46
     47	preempt_disable();
     48	tag = PPC_DBELL_LPID(get_lpid(vcpu)) | vcpu->vcpu_id;
     49	mb();
     50	ppc_msgsnd(dbell_type, 0, tag);
     51	preempt_enable();
     52}
     53
     54/* gtlbe must not be mapped by more than one host tlb entry */
     55void kvmppc_e500_tlbil_one(struct kvmppc_vcpu_e500 *vcpu_e500,
     56			   struct kvm_book3e_206_tlb_entry *gtlbe)
     57{
     58	unsigned int tid, ts;
     59	gva_t eaddr;
     60	u32 val;
     61	unsigned long flags;
     62
     63	ts = get_tlb_ts(gtlbe);
     64	tid = get_tlb_tid(gtlbe);
     65
     66	/* We search the host TLB to invalidate its shadow TLB entry */
     67	val = (tid << 16) | ts;
     68	eaddr = get_tlb_eaddr(gtlbe);
     69
     70	local_irq_save(flags);
     71
     72	mtspr(SPRN_MAS6, val);
     73	mtspr(SPRN_MAS5, MAS5_SGS | get_lpid(&vcpu_e500->vcpu));
     74
     75	asm volatile("tlbsx 0, %[eaddr]\n" : : [eaddr] "r" (eaddr));
     76	val = mfspr(SPRN_MAS1);
     77	if (val & MAS1_VALID) {
     78		mtspr(SPRN_MAS1, val & ~MAS1_VALID);
     79		asm volatile("tlbwe");
     80	}
     81	mtspr(SPRN_MAS5, 0);
     82	/* NOTE: tlbsx also updates mas8, so clear it for host tlbwe */
     83	mtspr(SPRN_MAS8, 0);
     84	isync();
     85
     86	local_irq_restore(flags);
     87}
     88
     89void kvmppc_e500_tlbil_all(struct kvmppc_vcpu_e500 *vcpu_e500)
     90{
     91	unsigned long flags;
     92
     93	local_irq_save(flags);
     94	mtspr(SPRN_MAS5, MAS5_SGS | get_lpid(&vcpu_e500->vcpu));
     95	asm volatile("tlbilxlpid");
     96	mtspr(SPRN_MAS5, 0);
     97	local_irq_restore(flags);
     98}
     99
    100void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid)
    101{
    102	vcpu->arch.pid = pid;
    103}
    104
    105void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr)
    106{
    107}
    108
    109/* We use two lpids per VM */
    110static DEFINE_PER_CPU(struct kvm_vcpu *[KVMPPC_NR_LPIDS], last_vcpu_of_lpid);
    111
    112static void kvmppc_core_vcpu_load_e500mc(struct kvm_vcpu *vcpu, int cpu)
    113{
    114	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
    115
    116	kvmppc_booke_vcpu_load(vcpu, cpu);
    117
    118	mtspr(SPRN_LPID, get_lpid(vcpu));
    119	mtspr(SPRN_EPCR, vcpu->arch.shadow_epcr);
    120	mtspr(SPRN_GPIR, vcpu->vcpu_id);
    121	mtspr(SPRN_MSRP, vcpu->arch.shadow_msrp);
    122	vcpu->arch.eplc = EPC_EGS | (get_lpid(vcpu) << EPC_ELPID_SHIFT);
    123	vcpu->arch.epsc = vcpu->arch.eplc;
    124	mtspr(SPRN_EPLC, vcpu->arch.eplc);
    125	mtspr(SPRN_EPSC, vcpu->arch.epsc);
    126
    127	mtspr(SPRN_GIVPR, vcpu->arch.ivpr);
    128	mtspr(SPRN_GIVOR2, vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE]);
    129	mtspr(SPRN_GIVOR8, vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL]);
    130	mtspr(SPRN_GSPRG0, (unsigned long)vcpu->arch.shared->sprg0);
    131	mtspr(SPRN_GSPRG1, (unsigned long)vcpu->arch.shared->sprg1);
    132	mtspr(SPRN_GSPRG2, (unsigned long)vcpu->arch.shared->sprg2);
    133	mtspr(SPRN_GSPRG3, (unsigned long)vcpu->arch.shared->sprg3);
    134
    135	mtspr(SPRN_GSRR0, vcpu->arch.shared->srr0);
    136	mtspr(SPRN_GSRR1, vcpu->arch.shared->srr1);
    137
    138	mtspr(SPRN_GEPR, vcpu->arch.epr);
    139	mtspr(SPRN_GDEAR, vcpu->arch.shared->dar);
    140	mtspr(SPRN_GESR, vcpu->arch.shared->esr);
    141
    142	if (vcpu->arch.oldpir != mfspr(SPRN_PIR) ||
    143	    __this_cpu_read(last_vcpu_of_lpid[get_lpid(vcpu)]) != vcpu) {
    144		kvmppc_e500_tlbil_all(vcpu_e500);
    145		__this_cpu_write(last_vcpu_of_lpid[get_lpid(vcpu)], vcpu);
    146	}
    147}
    148
    149static void kvmppc_core_vcpu_put_e500mc(struct kvm_vcpu *vcpu)
    150{
    151	vcpu->arch.eplc = mfspr(SPRN_EPLC);
    152	vcpu->arch.epsc = mfspr(SPRN_EPSC);
    153
    154	vcpu->arch.shared->sprg0 = mfspr(SPRN_GSPRG0);
    155	vcpu->arch.shared->sprg1 = mfspr(SPRN_GSPRG1);
    156	vcpu->arch.shared->sprg2 = mfspr(SPRN_GSPRG2);
    157	vcpu->arch.shared->sprg3 = mfspr(SPRN_GSPRG3);
    158
    159	vcpu->arch.shared->srr0 = mfspr(SPRN_GSRR0);
    160	vcpu->arch.shared->srr1 = mfspr(SPRN_GSRR1);
    161
    162	vcpu->arch.epr = mfspr(SPRN_GEPR);
    163	vcpu->arch.shared->dar = mfspr(SPRN_GDEAR);
    164	vcpu->arch.shared->esr = mfspr(SPRN_GESR);
    165
    166	vcpu->arch.oldpir = mfspr(SPRN_PIR);
    167
    168	kvmppc_booke_vcpu_put(vcpu);
    169}
    170
    171int kvmppc_core_check_processor_compat(void)
    172{
    173	int r;
    174
    175	if (strcmp(cur_cpu_spec->cpu_name, "e500mc") == 0)
    176		r = 0;
    177	else if (strcmp(cur_cpu_spec->cpu_name, "e5500") == 0)
    178		r = 0;
    179#ifdef CONFIG_ALTIVEC
    180	/*
    181	 * Since guests have the privilege to enable AltiVec, we need AltiVec
    182	 * support in the host to save/restore their context.
    183	 * Don't use CPU_FTR_ALTIVEC to identify cores with AltiVec unit
    184	 * because it's cleared in the absence of CONFIG_ALTIVEC!
    185	 */
    186	else if (strcmp(cur_cpu_spec->cpu_name, "e6500") == 0)
    187		r = 0;
    188#endif
    189	else
    190		r = -ENOTSUPP;
    191
    192	return r;
    193}
    194
    195int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
    196{
    197	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
    198
    199	vcpu->arch.shadow_epcr = SPRN_EPCR_DSIGS | SPRN_EPCR_DGTMI | \
    200				 SPRN_EPCR_DUVD;
    201#ifdef CONFIG_64BIT
    202	vcpu->arch.shadow_epcr |= SPRN_EPCR_ICM;
    203#endif
    204	vcpu->arch.shadow_msrp = MSRP_UCLEP | MSRP_PMMP;
    205
    206	vcpu->arch.pvr = mfspr(SPRN_PVR);
    207	vcpu_e500->svr = mfspr(SPRN_SVR);
    208
    209	vcpu->arch.cpu_type = KVM_CPU_E500MC;
    210
    211	return 0;
    212}
    213
    214static int kvmppc_core_get_sregs_e500mc(struct kvm_vcpu *vcpu,
    215					struct kvm_sregs *sregs)
    216{
    217	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
    218
    219	sregs->u.e.features |= KVM_SREGS_E_ARCH206_MMU | KVM_SREGS_E_PM |
    220			       KVM_SREGS_E_PC;
    221	sregs->u.e.impl_id = KVM_SREGS_E_IMPL_FSL;
    222
    223	sregs->u.e.impl.fsl.features = 0;
    224	sregs->u.e.impl.fsl.svr = vcpu_e500->svr;
    225	sregs->u.e.impl.fsl.hid0 = vcpu_e500->hid0;
    226	sregs->u.e.impl.fsl.mcar = vcpu_e500->mcar;
    227
    228	kvmppc_get_sregs_e500_tlb(vcpu, sregs);
    229
    230	sregs->u.e.ivor_high[3] =
    231		vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR];
    232	sregs->u.e.ivor_high[4] = vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL];
    233	sregs->u.e.ivor_high[5] = vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL_CRIT];
    234
    235	return kvmppc_get_sregs_ivor(vcpu, sregs);
    236}
    237
    238static int kvmppc_core_set_sregs_e500mc(struct kvm_vcpu *vcpu,
    239					struct kvm_sregs *sregs)
    240{
    241	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
    242	int ret;
    243
    244	if (sregs->u.e.impl_id == KVM_SREGS_E_IMPL_FSL) {
    245		vcpu_e500->svr = sregs->u.e.impl.fsl.svr;
    246		vcpu_e500->hid0 = sregs->u.e.impl.fsl.hid0;
    247		vcpu_e500->mcar = sregs->u.e.impl.fsl.mcar;
    248	}
    249
    250	ret = kvmppc_set_sregs_e500_tlb(vcpu, sregs);
    251	if (ret < 0)
    252		return ret;
    253
    254	if (!(sregs->u.e.features & KVM_SREGS_E_IVOR))
    255		return 0;
    256
    257	if (sregs->u.e.features & KVM_SREGS_E_PM) {
    258		vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] =
    259			sregs->u.e.ivor_high[3];
    260	}
    261
    262	if (sregs->u.e.features & KVM_SREGS_E_PC) {
    263		vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL] =
    264			sregs->u.e.ivor_high[4];
    265		vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL_CRIT] =
    266			sregs->u.e.ivor_high[5];
    267	}
    268
    269	return kvmppc_set_sregs_ivor(vcpu, sregs);
    270}
    271
    272static int kvmppc_get_one_reg_e500mc(struct kvm_vcpu *vcpu, u64 id,
    273			      union kvmppc_one_reg *val)
    274{
    275	int r = 0;
    276
    277	switch (id) {
    278	case KVM_REG_PPC_SPRG9:
    279		*val = get_reg_val(id, vcpu->arch.sprg9);
    280		break;
    281	default:
    282		r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
    283	}
    284
    285	return r;
    286}
    287
    288static int kvmppc_set_one_reg_e500mc(struct kvm_vcpu *vcpu, u64 id,
    289			      union kvmppc_one_reg *val)
    290{
    291	int r = 0;
    292
    293	switch (id) {
    294	case KVM_REG_PPC_SPRG9:
    295		vcpu->arch.sprg9 = set_reg_val(id, *val);
    296		break;
    297	default:
    298		r = kvmppc_set_one_reg_e500_tlb(vcpu, id, val);
    299	}
    300
    301	return r;
    302}
    303
    304static int kvmppc_core_vcpu_create_e500mc(struct kvm_vcpu *vcpu)
    305{
    306	struct kvmppc_vcpu_e500 *vcpu_e500;
    307	int err;
    308
    309	BUILD_BUG_ON(offsetof(struct kvmppc_vcpu_e500, vcpu) != 0);
    310	vcpu_e500 = to_e500(vcpu);
    311
    312	/* Invalid PIR value -- this LPID doesn't have valid state on any cpu */
    313	vcpu->arch.oldpir = 0xffffffff;
    314
    315	err = kvmppc_e500_tlb_init(vcpu_e500);
    316	if (err)
    317		return err;
    318
    319	vcpu->arch.shared = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
    320	if (!vcpu->arch.shared) {
    321		err = -ENOMEM;
    322		goto uninit_tlb;
    323	}
    324
    325	return 0;
    326
    327uninit_tlb:
    328	kvmppc_e500_tlb_uninit(vcpu_e500);
    329	return err;
    330}
    331
    332static void kvmppc_core_vcpu_free_e500mc(struct kvm_vcpu *vcpu)
    333{
    334	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
    335
    336	free_page((unsigned long)vcpu->arch.shared);
    337	kvmppc_e500_tlb_uninit(vcpu_e500);
    338}
    339
    340static int kvmppc_core_init_vm_e500mc(struct kvm *kvm)
    341{
    342	int lpid;
    343
    344	lpid = kvmppc_alloc_lpid();
    345	if (lpid < 0)
    346		return lpid;
    347
    348	/*
    349	 * Use two lpids per VM on cores with two threads like e6500. Use
    350	 * even numbers to speedup vcpu lpid computation with consecutive lpids
    351	 * per VM. vm1 will use lpids 2 and 3, vm2 lpids 4 and 5, and so on.
    352	 */
    353	if (threads_per_core == 2)
    354		lpid <<= 1;
    355
    356	kvm->arch.lpid = lpid;
    357	return 0;
    358}
    359
    360static void kvmppc_core_destroy_vm_e500mc(struct kvm *kvm)
    361{
    362	int lpid = kvm->arch.lpid;
    363
    364	if (threads_per_core == 2)
    365		lpid >>= 1;
    366
    367	kvmppc_free_lpid(lpid);
    368}
    369
    370static struct kvmppc_ops kvm_ops_e500mc = {
    371	.get_sregs = kvmppc_core_get_sregs_e500mc,
    372	.set_sregs = kvmppc_core_set_sregs_e500mc,
    373	.get_one_reg = kvmppc_get_one_reg_e500mc,
    374	.set_one_reg = kvmppc_set_one_reg_e500mc,
    375	.vcpu_load   = kvmppc_core_vcpu_load_e500mc,
    376	.vcpu_put    = kvmppc_core_vcpu_put_e500mc,
    377	.vcpu_create = kvmppc_core_vcpu_create_e500mc,
    378	.vcpu_free   = kvmppc_core_vcpu_free_e500mc,
    379	.init_vm = kvmppc_core_init_vm_e500mc,
    380	.destroy_vm = kvmppc_core_destroy_vm_e500mc,
    381	.emulate_op = kvmppc_core_emulate_op_e500,
    382	.emulate_mtspr = kvmppc_core_emulate_mtspr_e500,
    383	.emulate_mfspr = kvmppc_core_emulate_mfspr_e500,
    384	.create_vcpu_debugfs = kvmppc_create_vcpu_debugfs_e500,
    385};
    386
    387static int __init kvmppc_e500mc_init(void)
    388{
    389	int r;
    390
    391	r = kvmppc_booke_init();
    392	if (r)
    393		goto err_out;
    394
    395	/*
    396	 * Use two lpids per VM on dual threaded processors like e6500
    397	 * to workarround the lack of tlb write conditional instruction.
    398	 * Expose half the number of available hardware lpids to the lpid
    399	 * allocator.
    400	 */
    401	kvmppc_init_lpid(KVMPPC_NR_LPIDS/threads_per_core);
    402
    403	r = kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), 0, THIS_MODULE);
    404	if (r)
    405		goto err_out;
    406	kvm_ops_e500mc.owner = THIS_MODULE;
    407	kvmppc_pr_ops = &kvm_ops_e500mc;
    408
    409err_out:
    410	return r;
    411}
    412
    413static void __exit kvmppc_e500mc_exit(void)
    414{
    415	kvmppc_pr_ops = NULL;
    416	kvmppc_booke_exit();
    417}
    418
    419module_init(kvmppc_e500mc_init);
    420module_exit(kvmppc_e500mc_exit);
    421MODULE_ALIAS_MISCDEV(KVM_MINOR);
    422MODULE_ALIAS("devname:kvm");