File Index
Files and directories
Sign in
FILE

aia_imsic.c

File preview with syntax highlighting.

linux-6.19.14/arch/riscv/kvm/aia_imsic.c C
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (C) 2021 Western Digital Corporation or its affiliates.
   4 * Copyright (C) 2022 Ventana Micro Systems Inc.
   5 *
   6 * Authors:
   7 *	Anup Patel <apatel@ventanamicro.com>
   8 */
   9
  10#include <linux/atomic.h>
  11#include <linux/bitmap.h>
  12#include <linux/irqchip/riscv-imsic.h>
  13#include <linux/kvm_host.h>
  14#include <linux/math.h>
  15#include <linux/spinlock.h>
  16#include <linux/swab.h>
  17#include <kvm/iodev.h>
  18#include <asm/csr.h>
  19#include <asm/kvm_mmu.h>
  20
  21#define IMSIC_MAX_EIX	(IMSIC_MAX_ID / BITS_PER_TYPE(u64))
  22
  23struct imsic_mrif_eix {
  24	unsigned long eip[BITS_PER_TYPE(u64) / BITS_PER_LONG];
  25	unsigned long eie[BITS_PER_TYPE(u64) / BITS_PER_LONG];
  26};
  27
  28struct imsic_mrif {
  29	struct imsic_mrif_eix eix[IMSIC_MAX_EIX];
  30	unsigned long eithreshold;
  31	unsigned long eidelivery;
  32};
  33
  34struct imsic {
  35	struct kvm_io_device iodev;
  36
  37	u32 nr_msis;
  38	u32 nr_eix;
  39	u32 nr_hw_eix;
  40
  41	/*
  42	 * At any point in time, the register state is in
  43	 * one of the following places:
  44	 *
  45	 * 1) Hardware: IMSIC VS-file (vsfile_cpu >= 0)
  46	 * 2) Software: IMSIC SW-file (vsfile_cpu < 0)
  47	 */
  48
  49	/* IMSIC VS-file */
  50	rwlock_t vsfile_lock;
  51	int vsfile_cpu;
  52	int vsfile_hgei;
  53	void __iomem *vsfile_va;
  54	phys_addr_t vsfile_pa;
  55
  56	/* IMSIC SW-file */
  57	struct imsic_mrif *swfile;
  58	phys_addr_t swfile_pa;
  59	raw_spinlock_t swfile_extirq_lock;
  60};
  61
  62#define imsic_vs_csr_read(__c)			\
  63({						\
  64	unsigned long __r;			\
  65	csr_write(CSR_VSISELECT, __c);		\
  66	__r = csr_read(CSR_VSIREG);		\
  67	__r;					\
  68})
  69
  70#define imsic_read_switchcase(__ireg)			\
  71	case __ireg:					\
  72		return imsic_vs_csr_read(__ireg);
  73#define imsic_read_switchcase_2(__ireg)			\
  74	imsic_read_switchcase(__ireg + 0)		\
  75	imsic_read_switchcase(__ireg + 1)
  76#define imsic_read_switchcase_4(__ireg)			\
  77	imsic_read_switchcase_2(__ireg + 0)		\
  78	imsic_read_switchcase_2(__ireg + 2)
  79#define imsic_read_switchcase_8(__ireg)			\
  80	imsic_read_switchcase_4(__ireg + 0)		\
  81	imsic_read_switchcase_4(__ireg + 4)
  82#define imsic_read_switchcase_16(__ireg)		\
  83	imsic_read_switchcase_8(__ireg + 0)		\
  84	imsic_read_switchcase_8(__ireg + 8)
  85#define imsic_read_switchcase_32(__ireg)		\
  86	imsic_read_switchcase_16(__ireg + 0)		\
  87	imsic_read_switchcase_16(__ireg + 16)
  88#define imsic_read_switchcase_64(__ireg)		\
  89	imsic_read_switchcase_32(__ireg + 0)		\
  90	imsic_read_switchcase_32(__ireg + 32)
  91
  92static unsigned long imsic_eix_read(int ireg)
  93{
  94	switch (ireg) {
  95	imsic_read_switchcase_64(IMSIC_EIP0)
  96	imsic_read_switchcase_64(IMSIC_EIE0)
  97	}
  98
  99	return 0;
 100}
 101
 102#define imsic_vs_csr_swap(__c, __v)		\
 103({						\
 104	unsigned long __r;			\
 105	csr_write(CSR_VSISELECT, __c);		\
 106	__r = csr_swap(CSR_VSIREG, __v);	\
 107	__r;					\
 108})
 109
 110#define imsic_swap_switchcase(__ireg, __v)		\
 111	case __ireg:					\
 112		return imsic_vs_csr_swap(__ireg, __v);
 113#define imsic_swap_switchcase_2(__ireg, __v)		\
 114	imsic_swap_switchcase(__ireg + 0, __v)		\
 115	imsic_swap_switchcase(__ireg + 1, __v)
 116#define imsic_swap_switchcase_4(__ireg, __v)		\
 117	imsic_swap_switchcase_2(__ireg + 0, __v)	\
 118	imsic_swap_switchcase_2(__ireg + 2, __v)
 119#define imsic_swap_switchcase_8(__ireg, __v)		\
 120	imsic_swap_switchcase_4(__ireg + 0, __v)	\
 121	imsic_swap_switchcase_4(__ireg + 4, __v)
 122#define imsic_swap_switchcase_16(__ireg, __v)		\
 123	imsic_swap_switchcase_8(__ireg + 0, __v)	\
 124	imsic_swap_switchcase_8(__ireg + 8, __v)
 125#define imsic_swap_switchcase_32(__ireg, __v)		\
 126	imsic_swap_switchcase_16(__ireg + 0, __v)	\
 127	imsic_swap_switchcase_16(__ireg + 16, __v)
 128#define imsic_swap_switchcase_64(__ireg, __v)		\
 129	imsic_swap_switchcase_32(__ireg + 0, __v)	\
 130	imsic_swap_switchcase_32(__ireg + 32, __v)
 131
 132static unsigned long imsic_eix_swap(int ireg, unsigned long val)
 133{
 134	switch (ireg) {
 135	imsic_swap_switchcase_64(IMSIC_EIP0, val)
 136	imsic_swap_switchcase_64(IMSIC_EIE0, val)
 137	}
 138
 139	return 0;
 140}
 141
 142#define imsic_vs_csr_write(__c, __v)		\
 143do {						\
 144	csr_write(CSR_VSISELECT, __c);		\
 145	csr_write(CSR_VSIREG, __v);		\
 146} while (0)
 147
 148#define imsic_write_switchcase(__ireg, __v)		\
 149	case __ireg:					\
 150		imsic_vs_csr_write(__ireg, __v);	\
 151		break;
 152#define imsic_write_switchcase_2(__ireg, __v)		\
 153	imsic_write_switchcase(__ireg + 0, __v)		\
 154	imsic_write_switchcase(__ireg + 1, __v)
 155#define imsic_write_switchcase_4(__ireg, __v)		\
 156	imsic_write_switchcase_2(__ireg + 0, __v)	\
 157	imsic_write_switchcase_2(__ireg + 2, __v)
 158#define imsic_write_switchcase_8(__ireg, __v)		\
 159	imsic_write_switchcase_4(__ireg + 0, __v)	\
 160	imsic_write_switchcase_4(__ireg + 4, __v)
 161#define imsic_write_switchcase_16(__ireg, __v)		\
 162	imsic_write_switchcase_8(__ireg + 0, __v)	\
 163	imsic_write_switchcase_8(__ireg + 8, __v)
 164#define imsic_write_switchcase_32(__ireg, __v)		\
 165	imsic_write_switchcase_16(__ireg + 0, __v)	\
 166	imsic_write_switchcase_16(__ireg + 16, __v)
 167#define imsic_write_switchcase_64(__ireg, __v)		\
 168	imsic_write_switchcase_32(__ireg + 0, __v)	\
 169	imsic_write_switchcase_32(__ireg + 32, __v)
 170
 171static void imsic_eix_write(int ireg, unsigned long val)
 172{
 173	switch (ireg) {
 174	imsic_write_switchcase_64(IMSIC_EIP0, val)
 175	imsic_write_switchcase_64(IMSIC_EIE0, val)
 176	}
 177}
 178
 179#define imsic_vs_csr_set(__c, __v)		\
 180do {						\
 181	csr_write(CSR_VSISELECT, __c);		\
 182	csr_set(CSR_VSIREG, __v);		\
 183} while (0)
 184
 185#define imsic_set_switchcase(__ireg, __v)		\
 186	case __ireg:					\
 187		imsic_vs_csr_set(__ireg, __v);		\
 188		break;
 189#define imsic_set_switchcase_2(__ireg, __v)		\
 190	imsic_set_switchcase(__ireg + 0, __v)		\
 191	imsic_set_switchcase(__ireg + 1, __v)
 192#define imsic_set_switchcase_4(__ireg, __v)		\
 193	imsic_set_switchcase_2(__ireg + 0, __v)		\
 194	imsic_set_switchcase_2(__ireg + 2, __v)
 195#define imsic_set_switchcase_8(__ireg, __v)		\
 196	imsic_set_switchcase_4(__ireg + 0, __v)		\
 197	imsic_set_switchcase_4(__ireg + 4, __v)
 198#define imsic_set_switchcase_16(__ireg, __v)		\
 199	imsic_set_switchcase_8(__ireg + 0, __v)		\
 200	imsic_set_switchcase_8(__ireg + 8, __v)
 201#define imsic_set_switchcase_32(__ireg, __v)		\
 202	imsic_set_switchcase_16(__ireg + 0, __v)	\
 203	imsic_set_switchcase_16(__ireg + 16, __v)
 204#define imsic_set_switchcase_64(__ireg, __v)		\
 205	imsic_set_switchcase_32(__ireg + 0, __v)	\
 206	imsic_set_switchcase_32(__ireg + 32, __v)
 207
 208static void imsic_eix_set(int ireg, unsigned long val)
 209{
 210	switch (ireg) {
 211	imsic_set_switchcase_64(IMSIC_EIP0, val)
 212	imsic_set_switchcase_64(IMSIC_EIE0, val)
 213	}
 214}
 215
 216static unsigned long imsic_mrif_atomic_rmw(struct imsic_mrif *mrif,
 217					   unsigned long *ptr,
 218					   unsigned long new_val,
 219					   unsigned long wr_mask)
 220{
 221	unsigned long old_val = 0, tmp = 0;
 222
 223	__asm__ __volatile__ (
 224		"0:	lr.w.aq   %1, %0\n"
 225		"	and       %2, %1, %3\n"
 226		"	or        %2, %2, %4\n"
 227		"	sc.w.rl   %2, %2, %0\n"
 228		"	bnez      %2, 0b"
 229		: "+A" (*ptr), "+r" (old_val), "+r" (tmp)
 230		: "r" (~wr_mask), "r" (new_val & wr_mask)
 231		: "memory");
 232
 233	return old_val;
 234}
 235
 236static unsigned long imsic_mrif_atomic_or(struct imsic_mrif *mrif,
 237					  unsigned long *ptr,
 238					  unsigned long val)
 239{
 240	return atomic_long_fetch_or(val, (atomic_long_t *)ptr);
 241}
 242
 243#define imsic_mrif_atomic_write(__mrif, __ptr, __new_val)	\
 244		imsic_mrif_atomic_rmw(__mrif, __ptr, __new_val, -1UL)
 245#define imsic_mrif_atomic_read(__mrif, __ptr)			\
 246		imsic_mrif_atomic_or(__mrif, __ptr, 0)
 247
 248static u32 imsic_mrif_topei(struct imsic_mrif *mrif, u32 nr_eix, u32 nr_msis)
 249{
 250	struct imsic_mrif_eix *eix;
 251	u32 i, imin, imax, ei, max_msi;
 252	unsigned long eipend[BITS_PER_TYPE(u64) / BITS_PER_LONG];
 253	unsigned long eithreshold = imsic_mrif_atomic_read(mrif,
 254							&mrif->eithreshold);
 255
 256	max_msi = (eithreshold && (eithreshold <= nr_msis)) ?
 257		   eithreshold : nr_msis;
 258	for (ei = 0; ei < nr_eix; ei++) {
 259		eix = &mrif->eix[ei];
 260		eipend[0] = imsic_mrif_atomic_read(mrif, &eix->eie[0]) &
 261			    imsic_mrif_atomic_read(mrif, &eix->eip[0]);
 262#ifdef CONFIG_32BIT
 263		eipend[1] = imsic_mrif_atomic_read(mrif, &eix->eie[1]) &
 264			    imsic_mrif_atomic_read(mrif, &eix->eip[1]);
 265		if (!eipend[0] && !eipend[1])
 266#else
 267		if (!eipend[0])
 268#endif
 269			continue;
 270
 271		imin = ei * BITS_PER_TYPE(u64);
 272		imax = ((imin + BITS_PER_TYPE(u64)) < max_msi) ?
 273			imin + BITS_PER_TYPE(u64) : max_msi;
 274		for (i = (!imin) ? 1 : imin; i < imax; i++) {
 275			if (test_bit(i - imin, eipend))
 276				return (i << TOPEI_ID_SHIFT) | i;
 277		}
 278	}
 279
 280	return 0;
 281}
 282
 283static int imsic_mrif_isel_check(u32 nr_eix, unsigned long isel)
 284{
 285	u32 num = 0;
 286
 287	switch (isel) {
 288	case IMSIC_EIDELIVERY:
 289	case IMSIC_EITHRESHOLD:
 290		break;
 291	case IMSIC_EIP0 ... IMSIC_EIP63:
 292		num = isel - IMSIC_EIP0;
 293		break;
 294	case IMSIC_EIE0 ... IMSIC_EIE63:
 295		num = isel - IMSIC_EIE0;
 296		break;
 297	default:
 298		return -ENOENT;
 299	}
 300#ifndef CONFIG_32BIT
 301	if (num & 0x1)
 302		return -EINVAL;
 303#endif
 304	if ((num / 2) >= nr_eix)
 305		return -EINVAL;
 306
 307	return 0;
 308}
 309
 310static int imsic_mrif_rmw(struct imsic_mrif *mrif, u32 nr_eix,
 311			  unsigned long isel, unsigned long *val,
 312			  unsigned long new_val, unsigned long wr_mask)
 313{
 314	bool pend;
 315	struct imsic_mrif_eix *eix;
 316	unsigned long *ei, num, old_val = 0;
 317
 318	switch (isel) {
 319	case IMSIC_EIDELIVERY:
 320		old_val = imsic_mrif_atomic_rmw(mrif, &mrif->eidelivery,
 321						new_val, wr_mask & 0x1);
 322		break;
 323	case IMSIC_EITHRESHOLD:
 324		old_val = imsic_mrif_atomic_rmw(mrif, &mrif->eithreshold,
 325				new_val, wr_mask & (IMSIC_MAX_ID - 1));
 326		break;
 327	case IMSIC_EIP0 ... IMSIC_EIP63:
 328	case IMSIC_EIE0 ... IMSIC_EIE63:
 329		if (isel >= IMSIC_EIP0 && isel <= IMSIC_EIP63) {
 330			pend = true;
 331			num = isel - IMSIC_EIP0;
 332		} else {
 333			pend = false;
 334			num = isel - IMSIC_EIE0;
 335		}
 336
 337		if ((num / 2) >= nr_eix)
 338			return -EINVAL;
 339		eix = &mrif->eix[num / 2];
 340
 341#ifndef CONFIG_32BIT
 342		if (num & 0x1)
 343			return -EINVAL;
 344		ei = (pend) ? &eix->eip[0] : &eix->eie[0];
 345#else
 346		ei = (pend) ? &eix->eip[num & 0x1] : &eix->eie[num & 0x1];
 347#endif
 348
 349		/* Bit0 of EIP0 or EIE0 is read-only */
 350		if (!num)
 351			wr_mask &= ~BIT(0);
 352
 353		old_val = imsic_mrif_atomic_rmw(mrif, ei, new_val, wr_mask);
 354		break;
 355	default:
 356		return -ENOENT;
 357	}
 358
 359	if (val)
 360		*val = old_val;
 361
 362	return 0;
 363}
 364
 365struct imsic_vsfile_read_data {
 366	int hgei;
 367	u32 nr_eix;
 368	bool clear;
 369	struct imsic_mrif *mrif;
 370};
 371
 372static void imsic_vsfile_local_read(void *data)
 373{
 374	u32 i;
 375	struct imsic_mrif_eix *eix;
 376	struct imsic_vsfile_read_data *idata = data;
 377	struct imsic_mrif *mrif = idata->mrif;
 378	unsigned long new_hstatus, old_hstatus, old_vsiselect;
 379
 380	old_vsiselect = csr_read(CSR_VSISELECT);
 381	old_hstatus = csr_read(CSR_HSTATUS);
 382	new_hstatus = old_hstatus & ~HSTATUS_VGEIN;
 383	new_hstatus |= ((unsigned long)idata->hgei) << HSTATUS_VGEIN_SHIFT;
 384	csr_write(CSR_HSTATUS, new_hstatus);
 385
 386	/*
 387	 * We don't use imsic_mrif_atomic_xyz() functions to store
 388	 * values in MRIF because imsic_vsfile_read() is always called
 389	 * with pointer to temporary MRIF on stack.
 390	 */
 391
 392	if (idata->clear) {
 393		mrif->eidelivery = imsic_vs_csr_swap(IMSIC_EIDELIVERY, 0);
 394		mrif->eithreshold = imsic_vs_csr_swap(IMSIC_EITHRESHOLD, 0);
 395		for (i = 0; i < idata->nr_eix; i++) {
 396			eix = &mrif->eix[i];
 397			eix->eip[0] = imsic_eix_swap(IMSIC_EIP0 + i * 2, 0);
 398			eix->eie[0] = imsic_eix_swap(IMSIC_EIE0 + i * 2, 0);
 399#ifdef CONFIG_32BIT
 400			eix->eip[1] = imsic_eix_swap(IMSIC_EIP0 + i * 2 + 1, 0);
 401			eix->eie[1] = imsic_eix_swap(IMSIC_EIE0 + i * 2 + 1, 0);
 402#endif
 403		}
 404	} else {
 405		mrif->eidelivery = imsic_vs_csr_read(IMSIC_EIDELIVERY);
 406		mrif->eithreshold = imsic_vs_csr_read(IMSIC_EITHRESHOLD);
 407		for (i = 0; i < idata->nr_eix; i++) {
 408			eix = &mrif->eix[i];
 409			eix->eip[0] = imsic_eix_read(IMSIC_EIP0 + i * 2);
 410			eix->eie[0] = imsic_eix_read(IMSIC_EIE0 + i * 2);
 411#ifdef CONFIG_32BIT
 412			eix->eip[1] = imsic_eix_read(IMSIC_EIP0 + i * 2 + 1);
 413			eix->eie[1] = imsic_eix_read(IMSIC_EIE0 + i * 2 + 1);
 414#endif
 415		}
 416	}
 417
 418	csr_write(CSR_HSTATUS, old_hstatus);
 419	csr_write(CSR_VSISELECT, old_vsiselect);
 420}
 421
 422static void imsic_vsfile_read(int vsfile_hgei, int vsfile_cpu, u32 nr_eix,
 423			      bool clear, struct imsic_mrif *mrif)
 424{
 425	struct imsic_vsfile_read_data idata;
 426
 427	/* We can only read clear if we have a IMSIC VS-file */
 428	if (vsfile_cpu < 0 || vsfile_hgei <= 0)
 429		return;
 430
 431	/* We can only read clear on local CPU */
 432	idata.hgei = vsfile_hgei;
 433	idata.nr_eix = nr_eix;
 434	idata.clear = clear;
 435	idata.mrif = mrif;
 436	on_each_cpu_mask(cpumask_of(vsfile_cpu),
 437			 imsic_vsfile_local_read, &idata, 1);
 438}
 439
 440struct imsic_vsfile_rw_data {
 441	int hgei;
 442	int isel;
 443	bool write;
 444	unsigned long val;
 445};
 446
 447static void imsic_vsfile_local_rw(void *data)
 448{
 449	struct imsic_vsfile_rw_data *idata = data;
 450	unsigned long new_hstatus, old_hstatus, old_vsiselect;
 451
 452	old_vsiselect = csr_read(CSR_VSISELECT);
 453	old_hstatus = csr_read(CSR_HSTATUS);
 454	new_hstatus = old_hstatus & ~HSTATUS_VGEIN;
 455	new_hstatus |= ((unsigned long)idata->hgei) << HSTATUS_VGEIN_SHIFT;
 456	csr_write(CSR_HSTATUS, new_hstatus);
 457
 458	switch (idata->isel) {
 459	case IMSIC_EIDELIVERY:
 460		if (idata->write)
 461			imsic_vs_csr_write(IMSIC_EIDELIVERY, idata->val);
 462		else
 463			idata->val = imsic_vs_csr_read(IMSIC_EIDELIVERY);
 464		break;
 465	case IMSIC_EITHRESHOLD:
 466		if (idata->write)
 467			imsic_vs_csr_write(IMSIC_EITHRESHOLD, idata->val);
 468		else
 469			idata->val = imsic_vs_csr_read(IMSIC_EITHRESHOLD);
 470		break;
 471	case IMSIC_EIP0 ... IMSIC_EIP63:
 472	case IMSIC_EIE0 ... IMSIC_EIE63:
 473#ifndef CONFIG_32BIT
 474		if (idata->isel & 0x1)
 475			break;
 476#endif
 477		if (idata->write)
 478			imsic_eix_write(idata->isel, idata->val);
 479		else
 480			idata->val = imsic_eix_read(idata->isel);
 481		break;
 482	default:
 483		break;
 484	}
 485
 486	csr_write(CSR_HSTATUS, old_hstatus);
 487	csr_write(CSR_VSISELECT, old_vsiselect);
 488}
 489
 490static int imsic_vsfile_rw(int vsfile_hgei, int vsfile_cpu, u32 nr_eix,
 491			   unsigned long isel, bool write,
 492			   unsigned long *val)
 493{
 494	int rc;
 495	struct imsic_vsfile_rw_data rdata;
 496
 497	/* We can only access register if we have a IMSIC VS-file */
 498	if (vsfile_cpu < 0 || vsfile_hgei <= 0)
 499		return -EINVAL;
 500
 501	/* Check IMSIC register iselect */
 502	rc = imsic_mrif_isel_check(nr_eix, isel);
 503	if (rc)
 504		return rc;
 505
 506	/* We can only access register on local CPU */
 507	rdata.hgei = vsfile_hgei;
 508	rdata.isel = isel;
 509	rdata.write = write;
 510	rdata.val = (write) ? *val : 0;
 511	on_each_cpu_mask(cpumask_of(vsfile_cpu),
 512			 imsic_vsfile_local_rw, &rdata, 1);
 513
 514	if (!write)
 515		*val = rdata.val;
 516
 517	return 0;
 518}
 519
 520static void imsic_vsfile_local_clear(int vsfile_hgei, u32 nr_eix)
 521{
 522	u32 i;
 523	unsigned long new_hstatus, old_hstatus, old_vsiselect;
 524
 525	/* We can only zero-out if we have a IMSIC VS-file */
 526	if (vsfile_hgei <= 0)
 527		return;
 528
 529	old_vsiselect = csr_read(CSR_VSISELECT);
 530	old_hstatus = csr_read(CSR_HSTATUS);
 531	new_hstatus = old_hstatus & ~HSTATUS_VGEIN;
 532	new_hstatus |= ((unsigned long)vsfile_hgei) << HSTATUS_VGEIN_SHIFT;
 533	csr_write(CSR_HSTATUS, new_hstatus);
 534
 535	imsic_vs_csr_write(IMSIC_EIDELIVERY, 0);
 536	imsic_vs_csr_write(IMSIC_EITHRESHOLD, 0);
 537	for (i = 0; i < nr_eix; i++) {
 538		imsic_eix_write(IMSIC_EIP0 + i * 2, 0);
 539		imsic_eix_write(IMSIC_EIE0 + i * 2, 0);
 540#ifdef CONFIG_32BIT
 541		imsic_eix_write(IMSIC_EIP0 + i * 2 + 1, 0);
 542		imsic_eix_write(IMSIC_EIE0 + i * 2 + 1, 0);
 543#endif
 544	}
 545
 546	csr_write(CSR_HSTATUS, old_hstatus);
 547	csr_write(CSR_VSISELECT, old_vsiselect);
 548}
 549
 550static void imsic_vsfile_local_update(int vsfile_hgei, u32 nr_eix,
 551				      struct imsic_mrif *mrif)
 552{
 553	u32 i;
 554	struct imsic_mrif_eix *eix;
 555	unsigned long new_hstatus, old_hstatus, old_vsiselect;
 556
 557	/* We can only update if we have a HW IMSIC context */
 558	if (vsfile_hgei <= 0)
 559		return;
 560
 561	/*
 562	 * We don't use imsic_mrif_atomic_xyz() functions to read values
 563	 * from MRIF in this function because it is always called with
 564	 * pointer to temporary MRIF on stack.
 565	 */
 566
 567	old_vsiselect = csr_read(CSR_VSISELECT);
 568	old_hstatus = csr_read(CSR_HSTATUS);
 569	new_hstatus = old_hstatus & ~HSTATUS_VGEIN;
 570	new_hstatus |= ((unsigned long)vsfile_hgei) << HSTATUS_VGEIN_SHIFT;
 571	csr_write(CSR_HSTATUS, new_hstatus);
 572
 573	for (i = 0; i < nr_eix; i++) {
 574		eix = &mrif->eix[i];
 575		imsic_eix_set(IMSIC_EIP0 + i * 2, eix->eip[0]);
 576		imsic_eix_set(IMSIC_EIE0 + i * 2, eix->eie[0]);
 577#ifdef CONFIG_32BIT
 578		imsic_eix_set(IMSIC_EIP0 + i * 2 + 1, eix->eip[1]);
 579		imsic_eix_set(IMSIC_EIE0 + i * 2 + 1, eix->eie[1]);
 580#endif
 581	}
 582	imsic_vs_csr_write(IMSIC_EITHRESHOLD, mrif->eithreshold);
 583	imsic_vs_csr_write(IMSIC_EIDELIVERY, mrif->eidelivery);
 584
 585	csr_write(CSR_HSTATUS, old_hstatus);
 586	csr_write(CSR_VSISELECT, old_vsiselect);
 587}
 588
 589static void imsic_vsfile_cleanup(struct imsic *imsic)
 590{
 591	int old_vsfile_hgei, old_vsfile_cpu;
 592	unsigned long flags;
 593
 594	/*
 595	 * We don't use imsic_mrif_atomic_xyz() functions to clear the
 596	 * SW-file in this function because it is always called when the
 597	 * VCPU is being destroyed.
 598	 */
 599
 600	write_lock_irqsave(&imsic->vsfile_lock, flags);
 601	old_vsfile_hgei = imsic->vsfile_hgei;
 602	old_vsfile_cpu = imsic->vsfile_cpu;
 603	imsic->vsfile_cpu = imsic->vsfile_hgei = -1;
 604	imsic->vsfile_va = NULL;
 605	imsic->vsfile_pa = 0;
 606	write_unlock_irqrestore(&imsic->vsfile_lock, flags);
 607
 608	memset(imsic->swfile, 0, sizeof(*imsic->swfile));
 609
 610	if (old_vsfile_cpu >= 0)
 611		kvm_riscv_aia_free_hgei(old_vsfile_cpu, old_vsfile_hgei);
 612}
 613
 614static void imsic_swfile_extirq_update(struct kvm_vcpu *vcpu)
 615{
 616	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;
 617	struct imsic_mrif *mrif = imsic->swfile;
 618	unsigned long flags;
 619
 620	/*
 621	 * The critical section is necessary during external interrupt
 622	 * updates to avoid the risk of losing interrupts due to potential
 623	 * interruptions between reading topei and updating pending status.
 624	 */
 625
 626	raw_spin_lock_irqsave(&imsic->swfile_extirq_lock, flags);
 627
 628	if (imsic_mrif_atomic_read(mrif, &mrif->eidelivery) &&
 629	    imsic_mrif_topei(mrif, imsic->nr_eix, imsic->nr_msis))
 630		kvm_riscv_vcpu_set_interrupt(vcpu, IRQ_VS_EXT);
 631	else
 632		kvm_riscv_vcpu_unset_interrupt(vcpu, IRQ_VS_EXT);
 633
 634	raw_spin_unlock_irqrestore(&imsic->swfile_extirq_lock, flags);
 635}
 636
 637static void imsic_swfile_read(struct kvm_vcpu *vcpu, bool clear,
 638			      struct imsic_mrif *mrif)
 639{
 640	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;
 641
 642	/*
 643	 * We don't use imsic_mrif_atomic_xyz() functions to read and
 644	 * write SW-file and MRIF in this function because it is always
 645	 * called when VCPU is not using SW-file and the MRIF points to
 646	 * a temporary MRIF on stack.
 647	 */
 648
 649	memcpy(mrif, imsic->swfile, sizeof(*mrif));
 650	if (clear) {
 651		memset(imsic->swfile, 0, sizeof(*imsic->swfile));
 652		kvm_riscv_vcpu_unset_interrupt(vcpu, IRQ_VS_EXT);
 653	}
 654}
 655
 656static void imsic_swfile_update(struct kvm_vcpu *vcpu,
 657				struct imsic_mrif *mrif)
 658{
 659	u32 i;
 660	struct imsic_mrif_eix *seix, *eix;
 661	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;
 662	struct imsic_mrif *smrif = imsic->swfile;
 663
 664	imsic_mrif_atomic_write(smrif, &smrif->eidelivery, mrif->eidelivery);
 665	imsic_mrif_atomic_write(smrif, &smrif->eithreshold, mrif->eithreshold);
 666	for (i = 0; i < imsic->nr_eix; i++) {
 667		seix = &smrif->eix[i];
 668		eix = &mrif->eix[i];
 669		imsic_mrif_atomic_or(smrif, &seix->eip[0], eix->eip[0]);
 670		imsic_mrif_atomic_or(smrif, &seix->eie[0], eix->eie[0]);
 671#ifdef CONFIG_32BIT
 672		imsic_mrif_atomic_or(smrif, &seix->eip[1], eix->eip[1]);
 673		imsic_mrif_atomic_or(smrif, &seix->eie[1], eix->eie[1]);
 674#endif
 675	}
 676
 677	imsic_swfile_extirq_update(vcpu);
 678}
 679
 680bool kvm_riscv_vcpu_aia_imsic_has_interrupt(struct kvm_vcpu *vcpu)
 681{
 682	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;
 683	unsigned long flags;
 684	bool ret = false;
 685
 686	/*
 687	 * The IMSIC SW-file directly injects interrupt via hvip so
 688	 * only check for interrupt when IMSIC VS-file is being used.
 689	 */
 690
 691	read_lock_irqsave(&imsic->vsfile_lock, flags);
 692	if (imsic->vsfile_cpu > -1) {
 693		/*
 694		 * This function is typically called from kvm_vcpu_block() via
 695		 * kvm_arch_vcpu_runnable() upon WFI trap. The kvm_vcpu_block()
 696		 * can be preempted and the blocking VCPU might resume on a
 697		 * different CPU. This means it is possible that current CPU
 698		 * does not match the imsic->vsfile_cpu hence this function
 699		 * must check imsic->vsfile_cpu before accessing HGEIP CSR.
 700		 */
 701		if (imsic->vsfile_cpu != vcpu->cpu)
 702			ret = true;
 703		else
 704			ret = !!(csr_read(CSR_HGEIP) & BIT(imsic->vsfile_hgei));
 705	}
 706	read_unlock_irqrestore(&imsic->vsfile_lock, flags);
 707
 708	return ret;
 709}
 710
 711void kvm_riscv_vcpu_aia_imsic_load(struct kvm_vcpu *vcpu, int cpu)
 712{
 713	/*
 714	 * No need to explicitly clear HGEIE CSR bits because the
 715	 * hgei interrupt handler (aka hgei_interrupt()) will always
 716	 * clear it for us.
 717	 */
 718}
 719
 720void kvm_riscv_vcpu_aia_imsic_put(struct kvm_vcpu *vcpu)
 721{
 722	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;
 723	unsigned long flags;
 724
 725	if (!kvm_vcpu_is_blocking(vcpu))
 726		return;
 727
 728	read_lock_irqsave(&imsic->vsfile_lock, flags);
 729	if (imsic->vsfile_cpu > -1)
 730		csr_set(CSR_HGEIE, BIT(imsic->vsfile_hgei));
 731	read_unlock_irqrestore(&imsic->vsfile_lock, flags);
 732}
 733
 734void kvm_riscv_vcpu_aia_imsic_release(struct kvm_vcpu *vcpu)
 735{
 736	unsigned long flags;
 737	struct imsic_mrif tmrif;
 738	int old_vsfile_hgei, old_vsfile_cpu;
 739	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;
 740
 741	/* Read and clear IMSIC VS-file details */
 742	write_lock_irqsave(&imsic->vsfile_lock, flags);
 743	old_vsfile_hgei = imsic->vsfile_hgei;
 744	old_vsfile_cpu = imsic->vsfile_cpu;
 745	imsic->vsfile_cpu = imsic->vsfile_hgei = -1;
 746	imsic->vsfile_va = NULL;
 747	imsic->vsfile_pa = 0;
 748	write_unlock_irqrestore(&imsic->vsfile_lock, flags);
 749
 750	/* Do nothing, if no IMSIC VS-file to release */
 751	if (old_vsfile_cpu < 0)
 752		return;
 753
 754	/*
 755	 * At this point, all interrupt producers are still using
 756	 * the old IMSIC VS-file so we first re-direct all interrupt
 757	 * producers.
 758	 */
 759
 760	/* Purge the G-stage mapping */
 761	kvm_riscv_mmu_iounmap(vcpu->kvm, vcpu->arch.aia_context.imsic_addr,
 762			      IMSIC_MMIO_PAGE_SZ);
 763
 764	/* TODO: Purge the IOMMU mapping ??? */
 765
 766	/*
 767	 * At this point, all interrupt producers have been re-directed
 768	 * to somewhere else so we move register state from the old IMSIC
 769	 * VS-file to the IMSIC SW-file.
 770	 */
 771
 772	/* Read and clear register state from old IMSIC VS-file */
 773	memset(&tmrif, 0, sizeof(tmrif));
 774	imsic_vsfile_read(old_vsfile_hgei, old_vsfile_cpu, imsic->nr_hw_eix,
 775			  true, &tmrif);
 776
 777	/* Update register state in IMSIC SW-file */
 778	imsic_swfile_update(vcpu, &tmrif);
 779
 780	/* Free-up old IMSIC VS-file */
 781	kvm_riscv_aia_free_hgei(old_vsfile_cpu, old_vsfile_hgei);
 782}
 783
 784int kvm_riscv_vcpu_aia_imsic_update(struct kvm_vcpu *vcpu)
 785{
 786	unsigned long flags;
 787	phys_addr_t new_vsfile_pa;
 788	struct imsic_mrif tmrif;
 789	void __iomem *new_vsfile_va;
 790	struct kvm *kvm = vcpu->kvm;
 791	struct kvm_run *run = vcpu->run;
 792	struct kvm_vcpu_aia *vaia = &vcpu->arch.aia_context;
 793	struct imsic *imsic = vaia->imsic_state;
 794	int ret = 0, new_vsfile_hgei = -1, old_vsfile_hgei, old_vsfile_cpu;
 795
 796	/* Do nothing for emulation mode */
 797	if (kvm->arch.aia.mode == KVM_DEV_RISCV_AIA_MODE_EMUL)
 798		return 1;
 799
 800	/* Read old IMSIC VS-file details */
 801	read_lock_irqsave(&imsic->vsfile_lock, flags);
 802	old_vsfile_hgei = imsic->vsfile_hgei;
 803	old_vsfile_cpu = imsic->vsfile_cpu;
 804	read_unlock_irqrestore(&imsic->vsfile_lock, flags);
 805
 806	/* Do nothing if we are continuing on same CPU */
 807	if (old_vsfile_cpu == vcpu->cpu)
 808		return 1;
 809
 810	/* Allocate new IMSIC VS-file */
 811	ret = kvm_riscv_aia_alloc_hgei(vcpu->cpu, vcpu,
 812				       &new_vsfile_va, &new_vsfile_pa);
 813	if (ret <= 0) {
 814		/* For HW acceleration mode, we can't continue */
 815		if (kvm->arch.aia.mode == KVM_DEV_RISCV_AIA_MODE_HWACCEL) {
 816			run->fail_entry.hardware_entry_failure_reason =
 817								KVM_EXIT_FAIL_ENTRY_NO_VSFILE;
 818			run->fail_entry.cpu = vcpu->cpu;
 819			run->exit_reason = KVM_EXIT_FAIL_ENTRY;
 820			return 0;
 821		}
 822
 823		/* Release old IMSIC VS-file */
 824		if (old_vsfile_cpu >= 0)
 825			kvm_riscv_vcpu_aia_imsic_release(vcpu);
 826
 827		/* For automatic mode, we continue */
 828		goto done;
 829	}
 830	new_vsfile_hgei = ret;
 831
 832	/*
 833	 * At this point, all interrupt producers are still using
 834	 * to the old IMSIC VS-file so we first move all interrupt
 835	 * producers to the new IMSIC VS-file.
 836	 */
 837
 838	/* Ensure HGEIE CSR bit is zero before using the new IMSIC VS-file */
 839	csr_clear(CSR_HGEIE, BIT(new_vsfile_hgei));
 840
 841	/* Zero-out new IMSIC VS-file */
 842	imsic_vsfile_local_clear(new_vsfile_hgei, imsic->nr_hw_eix);
 843
 844	/* Update G-stage mapping for the new IMSIC VS-file */
 845	ret = kvm_riscv_mmu_ioremap(kvm, vcpu->arch.aia_context.imsic_addr,
 846				    new_vsfile_pa, IMSIC_MMIO_PAGE_SZ,
 847				    true, true);
 848	if (ret)
 849		goto fail_free_vsfile_hgei;
 850
 851	/* TODO: Update the IOMMU mapping ??? */
 852
 853	/* Update new IMSIC VS-file details in IMSIC context */
 854	write_lock_irqsave(&imsic->vsfile_lock, flags);
 855	imsic->vsfile_hgei = new_vsfile_hgei;
 856	imsic->vsfile_cpu = vcpu->cpu;
 857	imsic->vsfile_va = new_vsfile_va;
 858	imsic->vsfile_pa = new_vsfile_pa;
 859	write_unlock_irqrestore(&imsic->vsfile_lock, flags);
 860
 861	/*
 862	 * At this point, all interrupt producers have been moved
 863	 * to the new IMSIC VS-file so we move register state from
 864	 * the old IMSIC VS/SW-file to the new IMSIC VS-file.
 865	 */
 866
 867	memset(&tmrif, 0, sizeof(tmrif));
 868	if (old_vsfile_cpu >= 0) {
 869		/* Read and clear register state from old IMSIC VS-file */
 870		imsic_vsfile_read(old_vsfile_hgei, old_vsfile_cpu,
 871				  imsic->nr_hw_eix, true, &tmrif);
 872
 873		/* Free-up old IMSIC VS-file */
 874		kvm_riscv_aia_free_hgei(old_vsfile_cpu, old_vsfile_hgei);
 875	} else {
 876		/* Read and clear register state from IMSIC SW-file */
 877		imsic_swfile_read(vcpu, true, &tmrif);
 878	}
 879
 880	/* Restore register state in the new IMSIC VS-file */
 881	imsic_vsfile_local_update(new_vsfile_hgei, imsic->nr_hw_eix, &tmrif);
 882
 883done:
 884	/* Set VCPU HSTATUS.VGEIN to new IMSIC VS-file */
 885	vcpu->arch.guest_context.hstatus &= ~HSTATUS_VGEIN;
 886	if (new_vsfile_hgei > 0)
 887		vcpu->arch.guest_context.hstatus |=
 888			((unsigned long)new_vsfile_hgei) << HSTATUS_VGEIN_SHIFT;
 889
 890	/* Continue run-loop */
 891	return 1;
 892
 893fail_free_vsfile_hgei:
 894	kvm_riscv_aia_free_hgei(vcpu->cpu, new_vsfile_hgei);
 895	return ret;
 896}
 897
 898int kvm_riscv_vcpu_aia_imsic_rmw(struct kvm_vcpu *vcpu, unsigned long isel,
 899				 unsigned long *val, unsigned long new_val,
 900				 unsigned long wr_mask)
 901{
 902	u32 topei;
 903	struct imsic_mrif_eix *eix;
 904	int r, rc = KVM_INSN_CONTINUE_NEXT_SEPC;
 905	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;
 906
 907	if (isel == KVM_RISCV_AIA_IMSIC_TOPEI) {
 908		/* Read pending and enabled interrupt with highest priority */
 909		topei = imsic_mrif_topei(imsic->swfile, imsic->nr_eix,
 910					 imsic->nr_msis);
 911		if (val)
 912			*val = topei;
 913
 914		/* Writes ignore value and clear top pending interrupt */
 915		if (topei && wr_mask) {
 916			topei >>= TOPEI_ID_SHIFT;
 917			if (topei) {
 918				eix = &imsic->swfile->eix[topei /
 919							  BITS_PER_TYPE(u64)];
 920				clear_bit(topei & (BITS_PER_TYPE(u64) - 1),
 921					  eix->eip);
 922			}
 923		}
 924	} else {
 925		r = imsic_mrif_rmw(imsic->swfile, imsic->nr_eix, isel,
 926				   val, new_val, wr_mask);
 927		/* Forward unknown IMSIC register to user-space */
 928		if (r)
 929			rc = (r == -ENOENT) ? 0 : KVM_INSN_ILLEGAL_TRAP;
 930	}
 931
 932	if (wr_mask)
 933		imsic_swfile_extirq_update(vcpu);
 934
 935	return rc;
 936}
 937
 938int kvm_riscv_aia_imsic_rw_attr(struct kvm *kvm, unsigned long type,
 939				bool write, unsigned long *val)
 940{
 941	u32 isel, vcpu_id;
 942	unsigned long flags;
 943	struct imsic *imsic;
 944	struct kvm_vcpu *vcpu;
 945	int rc, vsfile_hgei, vsfile_cpu;
 946
 947	if (!kvm_riscv_aia_initialized(kvm))
 948		return -ENODEV;
 949
 950	vcpu_id = KVM_DEV_RISCV_AIA_IMSIC_GET_VCPU(type);
 951	vcpu = kvm_get_vcpu_by_id(kvm, vcpu_id);
 952	if (!vcpu)
 953		return -ENODEV;
 954
 955	isel = KVM_DEV_RISCV_AIA_IMSIC_GET_ISEL(type);
 956	imsic = vcpu->arch.aia_context.imsic_state;
 957
 958	read_lock_irqsave(&imsic->vsfile_lock, flags);
 959
 960	rc = 0;
 961	vsfile_hgei = imsic->vsfile_hgei;
 962	vsfile_cpu = imsic->vsfile_cpu;
 963	if (vsfile_cpu < 0) {
 964		if (write) {
 965			rc = imsic_mrif_rmw(imsic->swfile, imsic->nr_eix,
 966					    isel, NULL, *val, -1UL);
 967			imsic_swfile_extirq_update(vcpu);
 968		} else
 969			rc = imsic_mrif_rmw(imsic->swfile, imsic->nr_eix,
 970					    isel, val, 0, 0);
 971	}
 972
 973	read_unlock_irqrestore(&imsic->vsfile_lock, flags);
 974
 975	if (!rc && vsfile_cpu >= 0)
 976		rc = imsic_vsfile_rw(vsfile_hgei, vsfile_cpu, imsic->nr_eix,
 977				     isel, write, val);
 978
 979	return rc;
 980}
 981
 982int kvm_riscv_aia_imsic_has_attr(struct kvm *kvm, unsigned long type)
 983{
 984	u32 isel, vcpu_id;
 985	struct imsic *imsic;
 986	struct kvm_vcpu *vcpu;
 987
 988	if (!kvm_riscv_aia_initialized(kvm))
 989		return -ENODEV;
 990
 991	vcpu_id = KVM_DEV_RISCV_AIA_IMSIC_GET_VCPU(type);
 992	vcpu = kvm_get_vcpu_by_id(kvm, vcpu_id);
 993	if (!vcpu)
 994		return -ENODEV;
 995
 996	isel = KVM_DEV_RISCV_AIA_IMSIC_GET_ISEL(type);
 997	imsic = vcpu->arch.aia_context.imsic_state;
 998	return imsic_mrif_isel_check(imsic->nr_eix, isel);
 999}
1000
1001void kvm_riscv_vcpu_aia_imsic_reset(struct kvm_vcpu *vcpu)
1002{
1003	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;
1004
1005	if (!imsic)
1006		return;
1007
1008	kvm_riscv_vcpu_aia_imsic_release(vcpu);
1009
1010	memset(imsic->swfile, 0, sizeof(*imsic->swfile));
1011}
1012
1013int kvm_riscv_vcpu_aia_imsic_inject(struct kvm_vcpu *vcpu,
1014				    u32 guest_index, u32 offset, u32 iid)
1015{
1016	unsigned long flags;
1017	struct imsic_mrif_eix *eix;
1018	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;
1019
1020	/* We only emulate one IMSIC MMIO page for each Guest VCPU */
1021	if (!imsic || !iid || guest_index ||
1022	    (offset != IMSIC_MMIO_SETIPNUM_LE &&
1023	     offset != IMSIC_MMIO_SETIPNUM_BE))
1024		return -ENODEV;
1025
1026	iid = (offset == IMSIC_MMIO_SETIPNUM_BE) ? __swab32(iid) : iid;
1027	if (imsic->nr_msis <= iid)
1028		return -EINVAL;
1029
1030	read_lock_irqsave(&imsic->vsfile_lock, flags);
1031
1032	if (imsic->vsfile_cpu >= 0) {
1033		writel(iid, imsic->vsfile_va + IMSIC_MMIO_SETIPNUM_LE);
1034	} else {
1035		eix = &imsic->swfile->eix[iid / BITS_PER_TYPE(u64)];
1036		set_bit(iid & (BITS_PER_TYPE(u64) - 1), eix->eip);
1037		imsic_swfile_extirq_update(vcpu);
1038	}
1039
1040	read_unlock_irqrestore(&imsic->vsfile_lock, flags);
1041
1042	return 0;
1043}
1044
1045static int imsic_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
1046			   gpa_t addr, int len, void *val)
1047{
1048	if (len != 4 || (addr & 0x3) != 0)
1049		return -EOPNOTSUPP;
1050
1051	*((u32 *)val) = 0;
1052
1053	return 0;
1054}
1055
1056static int imsic_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
1057			    gpa_t addr, int len, const void *val)
1058{
1059	struct kvm_msi msi = { 0 };
1060
1061	if (len != 4 || (addr & 0x3) != 0)
1062		return -EOPNOTSUPP;
1063
1064	msi.address_hi = addr >> 32;
1065	msi.address_lo = (u32)addr;
1066	msi.data = *((const u32 *)val);
1067	kvm_riscv_aia_inject_msi(vcpu->kvm, &msi);
1068
1069	return 0;
1070};
1071
1072static struct kvm_io_device_ops imsic_iodoev_ops = {
1073	.read = imsic_mmio_read,
1074	.write = imsic_mmio_write,
1075};
1076
1077int kvm_riscv_vcpu_aia_imsic_init(struct kvm_vcpu *vcpu)
1078{
1079	int ret = 0;
1080	struct imsic *imsic;
1081	struct page *swfile_page;
1082	struct kvm *kvm = vcpu->kvm;
1083
1084	/* Fail if we have zero IDs */
1085	if (!kvm->arch.aia.nr_ids)
1086		return -EINVAL;
1087
1088	/* Allocate IMSIC context */
1089	imsic = kzalloc(sizeof(*imsic), GFP_KERNEL);
1090	if (!imsic)
1091		return -ENOMEM;
1092	vcpu->arch.aia_context.imsic_state = imsic;
1093
1094	/* Setup IMSIC context  */
1095	imsic->nr_msis = kvm->arch.aia.nr_ids + 1;
1096	rwlock_init(&imsic->vsfile_lock);
1097	imsic->nr_eix = BITS_TO_U64(imsic->nr_msis);
1098	imsic->nr_hw_eix = BITS_TO_U64(kvm_riscv_aia_max_ids);
1099	imsic->vsfile_hgei = imsic->vsfile_cpu = -1;
1100
1101	/* Setup IMSIC SW-file */
1102	swfile_page = alloc_pages(GFP_KERNEL | __GFP_ZERO,
1103				  get_order(sizeof(*imsic->swfile)));
1104	if (!swfile_page) {
1105		ret = -ENOMEM;
1106		goto fail_free_imsic;
1107	}
1108	imsic->swfile = page_to_virt(swfile_page);
1109	imsic->swfile_pa = page_to_phys(swfile_page);
1110	raw_spin_lock_init(&imsic->swfile_extirq_lock);
1111
1112	/* Setup IO device */
1113	kvm_iodevice_init(&imsic->iodev, &imsic_iodoev_ops);
1114	mutex_lock(&kvm->slots_lock);
1115	ret = kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS,
1116				      vcpu->arch.aia_context.imsic_addr,
1117				      KVM_DEV_RISCV_IMSIC_SIZE,
1118				      &imsic->iodev);
1119	mutex_unlock(&kvm->slots_lock);
1120	if (ret)
1121		goto fail_free_swfile;
1122
1123	return 0;
1124
1125fail_free_swfile:
1126	free_pages((unsigned long)imsic->swfile,
1127		   get_order(sizeof(*imsic->swfile)));
1128fail_free_imsic:
1129	vcpu->arch.aia_context.imsic_state = NULL;
1130	kfree(imsic);
1131	return ret;
1132}
1133
1134void kvm_riscv_vcpu_aia_imsic_cleanup(struct kvm_vcpu *vcpu)
1135{
1136	struct kvm *kvm = vcpu->kvm;
1137	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;
1138
1139	if (!imsic)
1140		return;
1141
1142	imsic_vsfile_cleanup(imsic);
1143
1144	mutex_lock(&kvm->slots_lock);
1145	kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &imsic->iodev);
1146	mutex_unlock(&kvm->slots_lock);
1147
1148	free_pages((unsigned long)imsic->swfile,
1149		   get_order(sizeof(*imsic->swfile)));
1150
1151	vcpu->arch.aia_context.imsic_state = NULL;
1152	kfree(imsic);
1153}
~/ Read-only file preview.