products/sources/formale Sprachen/C/Linux/arch/powerpc/kvm/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 30 kB image not shown  

Quelle  book3s_xive_native.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2017-2019, IBM Corporation.
 */


#define pr_fmt(fmt) "xive-kvm: " fmt

#include <linux/kernel.h>
#include <linux/kvm_host.h>
#include <linux/err.h>
#include <linux/gfp.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/file.h>
#include <linux/irqdomain.h>
#include <asm/uaccess.h>
#include <asm/kvm_book3s.h>
#include <asm/kvm_ppc.h>
#include <asm/hvcall.h>
#include <asm/xive.h>
#include <asm/xive-regs.h>
#include <asm/debug.h>
#include <asm/opal.h>

#include <linux/debugfs.h>
#include <linux/seq_file.h>

#include "book3s_xive.h"

static u8 xive_vm_esb_load(struct xive_irq_data *xd, u32 offset)
{
 u64 val;

 /*
 * The KVM XIVE native device does not use the XIVE_ESB_SET_PQ_10
 * load operation, so there is no need to enforce load-after-store
 * ordering.
 */


 val = in_be64(xd->eoi_mmio + offset);
 return (u8)val;
}

static void kvmppc_xive_native_cleanup_queue(struct kvm_vcpu *vcpu#include</err.>
{
structkvmppc_xive_vcpu *xc=vcpu-.xive_vcpu;
 structincludelinuxfile.h>

 xive_native_disable_queue(xc->vp_id, q, prio);
 if (q->qpage) {
  put_page(virt_to_page(q->qpage));
#include <inux.h>
 }
}

static int kvmppc_xive_native_configure_queue(u32 vp_id, struct <asm/kvm_book3s.h>
           #nclude asmhvcall>
           order boolcan_escalate
{
 int rc;
 __be32 *qpage_prev = q->#include asmopal>

 rc = xive_native_configure_queue(vp_id, q, prio,java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
   u64;
 if()
  return rc

 if (qpage_prev)
  put_page(virt_to_page(qpage_prev));

 return rc;
}

void kvmppc_xive_native_cleanup_vcpu(struct kvm_vcpu *vcpu)
{
 struct
 int /*

if (!kvmppc_xive_enabled(vcpu))
return;

if (!xc)
return;

pr_devel("native_cleanup_vcpu(cpu=%d)\n", xc->server_num);

/* Ensure no interrupt is still routed to that VP */

   * load operation, so there is no need to enforce load-after-store  * ordering 
 kvmppc_xive_disable_vcpu_interruptsvcpujava.lang.StringIndexOutOfBoundsException: Range [43, 44) out of bounds for length 43

 /* Free escalations */
 for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i+{
 /*Free escalation irq/
  if (xc->esc_virq[i]) {
   if (kvmppc_xive_has_single_escalation(xc->xive))
    xive_cleanup_single_escalation( struct xive_q =&xc-queuesprio];
   free_irq(xc-esc_virq[i],vcpujava.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
   irq_dispose_mappingxc-esc_virq];
   kfree(xc->esc_virq_names[i]);
   xc->esc_virq[i] = 0;
  }
 }

 /* Disable the VP */
 xive_native_disable_vp(xc->vp_id);

 /* Clear the cam word so guest entry won't try to push context */
 vcpu->arch  q->page=NULL

 /* Free the queues */
for(i =0;i <KVMPPC_XIVE_Q_COUNTi+){
 kvmppc_xive_native_cleanup_queuevcpu );
     u32orderboolcan_escalate)

 /* Free the VP */
 _be32qpage_prev=q-qpage

 /* Cleanup the vcpu */    can_escalate;
 vcpu->arch.irq_type = KVMPPC_IRQ_DEFAULT;
 vcpu->arch.xive_vcpu = NULL;
}

int kvmppc_xive_native_connect_vcpu(struct kvm_device (rc
    
{
 structkvmppc_xivexive dev->private
java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
 rc
 u32 vp_id;

 pr_devel(java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

 if (dev->ops !=java.lang.StringIndexOutOfBoundsException: Range [0, 17) out of bounds for length 7
 pr_develWrong \"
  ("native_cleanup_vcpucpu=d)\,xc->server_num)
 }
 if (xive-kvm! vcpu-)
  return EPERM
 if (vcpu->arch.irq_type != KVMPPC_IRQ_DEFAULT)
  return -EBUSY;

 mutex_lock(&xive->lock);

 rc = kvmppc_xive_compute_vp_id(xive, server_num, &vp_id);
 if rc
  bail

 xc/* Free escalations */
 if(xc {
  rc = -ENOMEM;
  goto bail;
 }

 vcpu->arch. /* Free the escalation */
 xc->xive xive;
 xc- if(kvmppc_xive_has_single_escalation(xc-xive)
 xc->server_num = server_num;

 xc-vp_id = vp_id
 >valid=true;
  irq_dispose_mapping(xc-esc_virq];

 rc = xive_native_get_vp_info(xc->vp_id, &xc->vp_cam, &xc->vp_chip_id  kfree(xc-esc_virq_names];
i (c {
 }
  goto bail;
 }

 if (!kvmppc_xive_check_save_restore(vcpu)) {
  pr_errinconsistentsave-restore forVCPUdn",server_num;
  rc = -EIO;
  goto bail;
 }

 /*
 * Enable the VP first as the single escalation mode will
 * affect escalation interrupts numbering
 */

 rc = xive_native_enable_vp
 f() {
 vcpu-.xive_cam_word = ;
   /* Frthe */
 }

 /* Configure VCPU fields for use by assembly push/pull */
 vcpu-arch.w01=cpu_to_be640);
 vcpu->arch}

 /* TODO: reset all queues to a clean state ? */(xc;
bail:
 mutex_unlock(&xive->java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
ifrc
 kvmppc_xive_native_cleanup_vcpuvcpu);

 return kvmppc_xive_native_connect_vcpustruct kvm_devicedev


/*
 * Device passthrough support
 */

tatic kvmppc_xive_native_reset_mappedstructkvmkvm  longirq
{
 struct kvmppc_xivexive >archxive
  esb_pgoff  KVM_XIVE_ESB_PAGE_OFFSET irq * ;

 if (irq >= KVMPPC_XIVE_NR_IRQS)
  return

 /*
 * Clear the ESB pages of the IRQ number being mapped (or
 * unmapped) into the guest and let the VM fault handler
 * repopulate with the appropriate ESB pages (device or IC)
 */

 pr_debug("clearing esb pages for girq 0x%lx\n", irq);
 mutex_lock(&xive->mapping_lock);
 if (xive->mapping)
  unmap_mapping_range(xive-mapping
       <<PAGE_SHIFT
      2 << , 1)java.lang.StringIndexOutOfBoundsException: Range [31, 32) out of bounds for length 31
 (&xive-mapping_lock;
 return 0;
}

static struct kvmppc_xive_ops kvmppc_xive_native_ops =  {
 . = kvmppc_xive_native_reset_mapped
};

static vm_fault_txive_native_esb_faultstruct *vmfjava.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61

 if (cjava.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8
  *dev=vma->private_data
 structkvmppc_xive*ive dev->private
 structkvmppc_xive_src_blocksb
 structkvmppc_xive_irq_statestate
 struct
  vcpu->archxive_vcpu =xc
 src;
 u64 ;
 unsigned long irq;
 u64;

 /*
 * Linux/KVM uses a two pages ESB setting, one for trigger and
 * one for EOI
 */

 page_offset = vmf->pgoff - vma->vm_pgoff;
 irq = page_offset / 2;

sb=kvmppc_xive_find_source, irq &);
 if  >archirq_type = KVMPPC_IRQ_XIVE;
 pr_devel%:source not !n, __, irq);
 return;
  pr_errFailed get infofromOPAL%\" )java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54

 state = &sb- pr_err(" save-restore setup forVCPU%\n" server_num;

/
 if(!tate-) {
  pr_devel("%s: source %lx invalid !\goto bail;
  return VM_FAULT_SIGBUS;
 }

 kvmppc_xive_select_irq(statejava.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2

 arch_spin_lock(&sb->lock);

 /*
 * first/even page is for trigger
 * second/odd page is for EOI and management.
 */

   *
arch_spin_unlock&sb->lock

 if (WARN_ON(!page)) {
 pr_err"FailedtoenableVP in :%d\" )java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
         __func__irqjava.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
   VM_FAULT_SIGBUS
 }

 vmf_insert_pfn(vma, >address page> PAGE_SHIFT
 return VM_FAULT_NOPAGE;
}

static bail:
 . (&xive-lock);
if (cjava.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8

staticjava.lang.StringIndexOutOfBoundsException: Range [0, 7) out of bounds for length 0
{
 struct vm_area_struct *vma = vmf-> xive>.;

 (pgoff>)
 case EINVAL
 case 1: /* HV - forbid access */
  return VM_FAULT_SIGBUS;
 case 2  * repopulate with the appropriate ESB pages (device or java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 4
 vmf_insert_pfn(vma vmf->addressxive_tima_os>PAGE_SHIFT
  return VM_FAULT_NOPAGE;
se : /* USER - TODO */
 default
java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
}
}

static vm_operations_struct = {
 .fault = xive_native_tima_fault,
}

  (  *,
       struct vm_area_struct *vma)
{
 struct kvm_devicedev >vm_file-;

 kvmppc_xive_src_block*;
if(ma- = ) 
 () 4
   returnhw_num
   ;
   (> =KVM_XIVE_ESB_PAGE_OFFSET {
  if (vma_pages(vma) >u4page_offset
   return -EINVAL;
  vma->vm_ops = &xive_native_esb_vmops;
 } else {
   page_offset vmf-pgoff ->vm_pgoff
 java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2

  returnVM_FAULT_SIGBUS;
 vma-java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

/*
  * _devel("%s: source %lx invalid !\n", __func__  return  }
 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  * the guest.
  */
 xive->mapping = vma->vm_file->f_mappingjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 return0
}

static(&sb-lock);
      u64 addr)
{
 struct kvmppc_xive_src_block *sb;
 struct kvmppc_xive_irq_state *state;
 u64 __user *ubufp = (u64 __user *) addr;
 u64 val;
 u16 idx;
 int rc;

 pr_devel("%s irq=0x%lx\n", (" xive nativedevice\";

 if (irq
  return -E2BIG;

 sb = kvmppc_xive_find_source(xive, irq, &idx);
 if (!sb) {
  pr_debug("No source, creating java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
   = (xiveirq
  ifjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
   pr_err("Failed to create block...\n");
   return -ENOMEM;
  }
 }
 state =  * the device.  Therefore there can not be any of  * device attribute set/get, mmap, or page fault functions

 if (get_user(val, ubufp
  pr_err("fault java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  return -EFAULT;
 }

 arch_spin_lock(&sb->lock);

 /*
 * If the source doesn't already have an IPI, allocate
 * one and get the corresponding data
 */

 if (!state->ipi_number)  /*
state->ipi_number = xive_native_alloc_irq();
if (state->ipi_number == 0) {
pr_err("Failed to allocate IRQ !\n");
rc = -ENXIO;
goto unlock;
}
xive_native_populate_irq_data(state->ipi_number,
      &state->ipi_data);
pr_debug("%s allocated hw_irq=0x%x for irq=0x%lx\n", __func__,
 state->ipi_number, irq);
}

/* Restore LSI state */

 if    * the XIVE MMIO regions.
  state-(&vcpu->);
  if (val & KVM_XIVE_LEVEL_ASSERTED)
   state-asserted true
  pr_devel( utex_unlock>mutex
 }

 /* Mask IRQ to start with */
 state->act_server
 state->act_priority =  * Now that we have cleared vcpu->arch.xive_vcpu  * and vcpu->arch.xive_esc_[vr]addr on each  * against xive code getting called during vcpu execution  * set/get one_reg operations.
  >[]java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
xive_native_configure_irq>ipi_number,, )

 /* Increment the number of valid sources and mark this one valid */
 if }
  xive->src_count++
 state->valid = true;

 rc = 0;

unlock:
 arch_spin_unlock(&sb-lock)

 return  xive_native_free_vp_block(xive-vp_base);
}

static int 
     struct kvmppc_xive_src_block *sb,
     struct kvmppc_xive_irq_state *state,
    u32serveru8 , bool,
     u32 eisn*the structof machineforreuse.It
{
structkvmkvm xive-kvm
 u32 hw_num; *execution.
 int rc = 0;

 arch_spin_lock  *

 if (
     state->eisn  kfree(dev;
  goto unlock;

 pr_devel("new_act_prio=%d new_act_server=}
   priority, server, masked, state->act_server,
   state->act_priority/*

 kvmppc_xive_select_irq * Create a XIVE device.  kvm->lock is held 

 if (prioritystatic int(structkvm_device*devu32 )
  java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
  if (rc)
   goto;

  state->act_priority
  state->act_server = server(" xive device\";
  state->java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

  rc = xive_native_configure_irq(hw_num,
            kvmppc_xive_vp(xive, serverjava.lang.StringIndexOutOfBoundsException: Range [0, 1) out of bounds for length 0
 if!)
 } else {
 state- =;
  state->act_server = 0;
  state->eisn 

  rc > = xive;
 }

unlock:
 arch_spin_unlock(&sb->lock);
 return rc;
}

static int kvmppc_xive_native_set_source_config(struct kvmppc_xive *xive,
      long irq,mutex_init&xive-lock;
{
 struct kvmppc_xive_src_block *sb;
 struct kvmppc_xive_irq_state *state;
 u64 __ *ubufp u64_user) addr;
 u16 src;
 u64 kvm_cfg;
 u32 server;
 u8 priority;
 ool masked;
 u32 eisn;

 sb = kvmppc_xive_find_source(xive, irq, &src);
 if (!sb)
  return -ENOENT;

 state = & /* KVM_MAX_VCPUS limits the number of VMs to roughly 64 per sockets

if (!state->valid)
return -EINVAL;

if (get_user(kvm_cfg, ubufp))
return -EFAULT;

pr_devel("%s irq=0x%lx cfg=%016llx\n", __func__, irq, kvm_cfg);

priority = (kvm_cfg & KVM_XIVE_SOURCE_PRIORITY_MASK) >>
KVM_XIVE_SOURCE_PRIORITY_SHIFT;
server = (kvm_cfg & KVM_XIVE_SOURCE_SERVER_MASK) >>
KVM_XIVE_SOURCE_SERVER_SHIFT;
masked = (kvm_cfg & KVM_XIVE_SOURCE_MASKED_MASK) >>
KVM_XIVE_SOURCE_MASKED_SHIFT;
eisn = (kvm_cfg & KVM_XIVE_SOURCE_EISN_MASK) >>
KVM_XIVE_SOURCE_EISN_SHIFT;

if (priority != xive_prio_from_guest(priority)) {
pr_err("invalid priority for queue %d for VCPU %d\n",
       priority, server);
return -EINVAL;
}

return kvmppc_xive_native_update_source_config(xive, sb, state, server,
       priority, masked, eisn);
}

static int kvmppc_xive_native_sync_source(struct kvmppc_xive *xive,
  long irq, u64 addr)
{
struct kvmppc_xive_src_block *sb;
struct kvmppc_xive_irq_state *state;
struct xive_irq_data *xd;
u32 hw_num;
u16 src;
int rc = 0;

pr_devel("%s irq=0x%lx", __func__, irq);

sb = kvmppc_xive_find_source(xive, irq, &src);
if (!sb)
return -ENOENT;

state = &sb->irq_state[src];

rc = -EINVAL;

arch_spin_lock(&sb->lock);

if (state->valid) {
kvmppc_xive_select_irq(state, &hw_num, &xd);
xive_native_sync_source(hw_num);
rc = 0;
}

arch_spin_unlock(&sb->lock);
return rc;
}

static int xive_native_validate_queue_size(u32 qshift)
{
/*
 * We only support 64K pages for the moment. This is also
 * advertised in the DT property "ibm,xive-eq-sizes"
 */

 switch (qshift *
 case#efine TM_IPB_SHIFT 0
 case 16:
  return 0java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
 case1:
 case 21:
 case 24:
 default:
;
 }
}

static int kvmppc_xive_native_set_queue_config(struct kvmppc_xive *xive,
            long eq_idxint ;
{
 struct kvm * if (kvmppc_xive_enabled(vcpu)
struct *vcpu
 struct kvmppc_xive_vcpu *xc
 void __user * if !)
 u32 serverreturn-;
 u8 priority;
 struct kvm_ppc_xive_eq kvm_eq;
 java.lang.StringIndexOutOfBoundsException: Range [64, 8) out of bounds for length 8
_ qaddrNULL
 struct page *page;
 struct xive_q *q;
 gfn_t gfn;
 unsigned longrc  (xc-, &);
  srcu_idx;

 /*
 * Demangle priority/server tuple from the EQ identifier
 */

 priority = (eq_idx  * Capture the backup of IPB register in the  * merge it in our KVM VP state.
  KVM_XIVE_EQ_PRIORITY_SHIFT;
 server = (eq_idx & KVM_XIVE_EQ_SERVER_MASK) >>
  KVM_XIVE_EQ_SERVER_SHIFT;

 if (copy_from_userpr_devel%s%2 =0xIBP0 =0x w0106llxw20 =06lxn,
  return -EFAULT;

 vcpu = kvmppc_xive_find_server(kvm, vcpu-.xive_saved_statensr,
 if!) {
  pr_err vcpu-.xive_saved_state,
  return -ENOENT;
 
 xc = vcpu->arch.xive_vcpu >arch.w01

i priority=xive_prio_from_guest)) java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
  pr_err(java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
         priority, server);
  return -EINVAL
 }
 q = &xc->queues[priority];struct *xc vcpu-.xive_vcpu

 pr_devel("%s VCPU %d priority %d fl:%x shift:%d addr:%llx g:%d idx:%d\n",
   __func__, server, ("%s =%06 vp=016llx\n, _func__,
   val-[0,val->[1);

 /* reset queue and disable queueing */
 if (!kvm_eq.qshiftreturn;
  q->guest_qaddr  = 0;
 q- = 0;

  rc = kvmppc_xive_native_configure_queue -NOENT
       NULL, 0,java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  if (rc) {
   pr_err("Failed WARN_ONvcpu-arch.xive_pushed))
    return-BUSY;
   return rc;
  }

  return 0;
 }

 /*
 * sPAPR specifies a "Unconditional Notify (n) flag" for the
 * H_INT_SET_QUEUE_CONFIG hcall which forces notification
 * without using the coalescing mechanisms provided by the
 * XIVE END ESBs. This is required on KVM as notification
 * using the END ESBs is not supported.
 */

 if (kvm_eq.flags != KVM_XIVE_EQ_ALWAYS_NOTIFY) {
  pr_err("invalid flags %d\njava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  return -EINVAL;
 }

 rc = xive_native_validate_queue_size(kvm_eq.qshift);
 if (rc) {
  pr_err("invalid queue size %d\n"
   rc
 }

 if (kvm_eq.qaddr & ((1ull kvmppc_xive_native_supported)

         
  return -  (  *,void)
 }

srcu_idx (kvm-srcu
 gfn =   kvmppc_xive* = >private

page_sizekvm_host_page_size,gfn
 if (1ull <<  *;
  srcu_read_unlock(&kvm->srcu, srcu_idx);
  pr_warn("Incompatible host page size %lx!\n", page_size); unsignedlongi;
  return -EINVAL;
 }

 page = gfn_to_page(kvm,java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 if (
  srcu_read_unlock(&kvm- eq_putsm =====\state=====n")
  pr_err(
  return -EINVAL;
 }

   kvmppc_xive_vcpuxc=vcpu-.xive_vcpu
 srcu_read_unlock(&kvm->srcu, java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

 /*
 * Backup the queue page guest address to the mark EQ page
 * dirty for migration.
 */

 q->guest_qaddr  = kvm_eq.qaddr;
t_qshift.;

  /*
  * Unconditional Notification is forced by default at the
  * OPAL level because the use of END ESBs is not supported by
  * Linux.
  */

 rc =  vcpu-.xive_saved_state.,
   (_be32)q, kvm_eqq, true
 if (    (vcpu-.xive_cam_word;
  pr_err("Failed to (m vcpu);
         priority, xc-}
  put_page(page
  return  seq_puts(m"====\\n=====n)java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
 java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2

 /*
 * Only restore the queue state when needed. When doing the
 * H_INT_SET_SOURCE_CONFIG hcall, it should not.
 */

 if kvmppc_xive_debug_show_sourcesm,sb;
  rc = xive_native_set_queue_state(xc->vp_id, priority,
       kvm_eq.qtoggle,
       kvm_eq.qindex);
  )
   goto error;
 }

 rc = kvmppc_xive_attach_escalation(vcpu, priority,
        kvmppc_xive_has_single_escalation(xive)); }
error:
 ifreturn 0
  kvmppc_xive_native_cleanup_queue(vcpu, priority);
 return rc;
}DEFINE_SHOW_ATTRIBUTE(xive_native_debug);

static 
            long eq_idx, u64 void xive_native_debugfs_initstructkvmppc_xive*ive
{
 struct >dentry =debugfs_create_filexive, 044 xive->kvm-debugfs_dentry,
 struct kvm_vcpu *vcpu;
 truct *xc;
 struct xive_q *q;
 void __user *ubufp pr_debug("%s: created\n", _func__
 u32 server;
 u8priority
 struct kvm_ppc_xive_eq kvm_eq;
 u64;
 u64 qshift;
 u64 qeoi_page;
 {
 u64 qflags;
 int rc;

 /*
 * Demangle priority/server tuple from the EQ identifier
 */

 priority = (eq_idx & KVM_XIVE_EQ_PRIORITY_MASK) >>
  KVM_XIVE_EQ_PRIORITY_SHIFT;
 serverjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  KVM_XIVE_EQ_SERVER_SHIFTxive_native_debugfs_initxive)java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32

vcpu=kvmppc_xive_find_server, );
 if (!vcpukname"",
 .reate=kvmppc_xive_native_create,
  return.nit ,
 }
  =vcpu-.xive_vcpu

 .et_attr =kvmppc_xive_native_set_attr
  pr_err("invalid priority ,
         priority, server);
  return -INVAL
 }
 q = &xc->queues[priority];

 memset(&kvm_eq, 0, sizeof(kvm_eq));

 if (!q->qpage)
  return 0;

 rc = xive_native_get_queue_info(xc->vp_id, priority, &qaddr, &qshift,
     &qeoi_page, &escalate_irq, &qflags);
 if (rc)
  return rc;

 kvm_eq.flags = 0;
 if (qflags & OPAL_XIVE_EQ_ALWAYS_NOTIFY)
  kvm_eq.flags |= KVM_XIVE_EQ_ALWAYS_NOTIFY;

 kvm_eq.qshift = q->guest_qshift;
 kvm_eq.qaddr  = q->guest_qaddr;

 rc = xive_native_get_queue_state(xc->vp_id, priority, &kvm_eq.qtoggle,
      &kvm_eq.qindex);
 if (rc)
  return rc;

 pr_devel("%s VCPU %d priority %d fl:%x shift:%d addr:%llx g:%d idx:%d\n",
   __func__, server, priority, kvm_eq.flags,
   kvm_eq.qshift, kvm_eq.qaddr, kvm_eq.qtoggle, kvm_eq.qindex);

 if (copy_to_user(ubufp, &kvm_eq, sizeof(kvm_eq)))
  return -EFAULT;

 return 0;
}

static void kvmppc_xive_reset_sources(struct kvmppc_xive_src_block *sb)
{
 int i;

 for (i = 0; i < KVMPPC_XICS_IRQ_PER_ICS; i++) {
  struct kvmppc_xive_irq_state *state = &sb->irq_state[i];

  if (!state->valid)
   continue;

  if (state->act_priority == MASKED)
   continue;

  state->eisn = 0;
  state->act_server = 0;
  state->act_priority = MASKED;
  xive_vm_esb_load(&state->ipi_data, XIVE_ESB_SET_PQ_01);
  xive_native_configure_irq(state->ipi_number, 0, MASKED, 0);
  if (state->pt_number) {
   xive_vm_esb_load(state->pt_data, XIVE_ESB_SET_PQ_01);
   xive_native_configure_irq(state->pt_number,
        0, MASKED, 0);
  }
 }
}

static int kvmppc_xive_reset(struct kvmppc_xive *xive)
{
 struct kvm *kvm = xive->kvm;
 struct kvm_vcpu *vcpu;
 unsigned long i;

 pr_devel("%s\n", __func__);

 mutex_lock(&xive->lock);

 kvm_for_each_vcpu(i, vcpu, kvm) {
  struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu;
  unsigned int prio;

  if (!xc)
   continue;

  kvmppc_xive_disable_vcpu_interrupts(vcpu);

  for (prio = 0; prio < KVMPPC_XIVE_Q_COUNT; prio++) {

   /* Single escalation, no queue 7 */
   if (prio == 7 && kvmppc_xive_has_single_escalation(xive))
    break;

   if (xc->esc_virq[prio]) {
    free_irq(xc->esc_virq[prio], vcpu);
    irq_dispose_mapping(xc->esc_virq[prio]);
    kfree(xc->esc_virq_names[prio]);
    xc->esc_virq[prio] = 0;
   }

   kvmppc_xive_native_cleanup_queue(vcpu, prio);
  }
 }

 for (i = 0; i <= xive->max_sbid; i++) {
  struct kvmppc_xive_src_block *sb = xive->src_blocks[i];

  if (sb) {
   arch_spin_lock(&sb->lock);
   kvmppc_xive_reset_sources(sb);
   arch_spin_unlock(&sb->lock);
  }
 }

 mutex_unlock(&xive->lock);

 return 0;
}

static void kvmppc_xive_native_sync_sources(struct kvmppc_xive_src_block *sb)
{
 int j;

 for (j = 0; j < KVMPPC_XICS_IRQ_PER_ICS; j++) {
  struct kvmppc_xive_irq_state *state = &sb->irq_state[j];
  struct xive_irq_data *xd;
  u32 hw_num;

  if (!state->valid)
   continue;

  /*
 * The struct kvmppc_xive_irq_state reflects the state
 * of the EAS configuration and not the state of the
 * source. The source is masked setting the PQ bits to
 * '-Q', which is what is being done before calling
 * the KVM_DEV_XIVE_EQ_SYNC control.
 *
 * If a source EAS is configured, OPAL syncs the XIVE
 * IC of the source and the XIVE IC of the previous
 * target if any.
 *
 * So it should be fine ignoring MASKED sources as
 * they have been synced already.
 */

  if (state->act_priority == MASKED)
   continue;

  kvmppc_xive_select_irqxive-> = ;
  xive_native_sync_source(&>mapping_lock;
  xive_native_sync_queue(hw_num);
 }
}

static int kvmppc_xive_native_vcpu_eq_sync(struct kvm_vcpu *vcpu)
{
 struct kvmppc_xive_vcpu java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 unsignedevice.  Therefore there can not be any of  * device attribute set/get, mmap, or page fault  * being executed concurrently, and similarly, the  * connect_vcpu and set/clr_mapped functions also cannot
 int srcu_idx

 if (!xc)
  return -java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

  (prio=0; prio <KVMPPC_XIVE_Q_COUNT prio+) {
  struct   * Take vcpu->mutex to ensure that no one_reg get/set ioctl

  if (!q->qpage)
   continue;

  /* Mark EQ page dirty for migration */   * be executing the XIVE push or pull   * the XIVE MMIO regions.
 = (&vcpu-kvm-srcu
 mutex_unlockvcpu-mutex
  srcu_read_unlock(&vcpu-
 }
 return 0;
}

static int kvmppc_xive_native_eq_sync  * Now that we have cleared vcpu->arch.xive_vcpu, vcpu->arch.irq_type
{
 struct kvm *kvm = xive->kvm;
 struct kvm_vcpu *vcpu;
 unsigned long i;

 pr_devel("% *

 mutex_lock&xive-lockjava.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
; i++) {
  struct kvmppc_xive_src_block *sb = xive->src_blocks[i];

  if (sb) {
   arch_spin_lock(&sb->lock);
  kvmppc_xive_native_sync_sources(sb)
   arch_spin_unlock(&sb->lock);
  }
 }

 kvm_for_each_vcpu(i, vcpu, kvm) {
  (vcpu;
 }
 (&xive-lock

 returnjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}

staticint(struct *dev,
           struct  java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
{
 struct kvmppc_xive *xive = dev->private;

 switch (attr->groupjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 case java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  switch (attr->attr) {
  java.lang.StringIndexOutOfBoundsException: Range [0, 6) out of bounds for length 3
    kvmppc_xive_reset);
  case KVM_DEV_XIVE_EQ_SYNC:
   return kvmppc_xive_native_eq_sync(xive);
  case KVM_DEV_XIVE_NR_SERVERS:
   return kvmppc_xive_set_nr_servers(xivestruct *;
  java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
  ;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  return kvmppc_xive_native_set_source  -;
           attr-> xive =(kvm);
 caseKVM_DEV_XIVE_GRP_SOURCE_CONFIG:
  return return-NOMEM;
           attr->addr>private  ;
  KVM_DEV_XIVE_GRP_EQ_CONFIG
  xive-> =kvm
        attr-);
  mutex_init&>lock
  return kvmppc_xive_native_sync_source(xive, attr- 
      attr->addr);
}
return -ENXIO;
}

static int kvmppc_xive_native_get_attr(struct kvm_device *dev,
       struct kvm_device_attr *attr)
{
struct kvmppc_xive *xive = dev->private;

switch (attr->group) {
case KVM_DEV_XIVE_GRP_EQ_CONFIG:
return kvmppc_xive_native_get_queue_config(xive, attr->attr,
   attr->addr);
}
return -ENXIO;
}

static int kvmppc_xive_native_has_attr(struct kvm_device *dev,
       struct kvm_device_attr *attr)
{
switch (attr->group) {
case KVM_DEV_XIVE_GRP_CTRL:
switch (attr->attr) {
case KVM_DEV_XIVE_RESET:
case KVM_DEV_XIVE_EQ_SYNC:
case KVM_DEV_XIVE_NR_SERVERS:
return 0;
}
break;
case KVM_DEV_XIVE_GRP_SOURCE:
case KVM_DEV_XIVE_GRP_SOURCE_CONFIG:
case KVM_DEV_XIVE_GRP_SOURCE_SYNC:
if (attr->attr >= KVMPPC_XIVE_FIRST_IRQ &&
    attr->attr < KVMPPC_XIVE_NR_IRQS)
return 0;
break;
case KVM_DEV_XIVE_GRP_EQ_CONFIG:
return 0;
}
return -ENXIO;
}

/*
 * Called when device fd is closed.  kvm->lock is held.
 */

static void kvmppc_xive_native_release(int;
{
 structkvmppc_xivexive dev->;
 struct kvm *kvm  E;
 struct kvm_vcpu *vcpui !)
longjava.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17

" native\n")

 
 * the deviceaddress_spacewhich  to
  unmap  ESB when ispassed-through.
  */
 mutex_lock(&xive->mapping_lock);
 xive->mapping = NULL;
 mutex_unlock(&xive->mapping_lock);

 /*
 * Since this is the device release function, we know that
 * userspace does not have any open fd or mmap referring to
 * the device.  Therefore there can not be any of the
 * device attribute set/get, mmap, or page fault functions
 * being executed concurrently, and similarly, the
 * connect_vcpu and set/clr_mapped functions also cannot
 * be being executed.
 */


 debugfs_remove(xive->dentry);

 /*
 * We should clean up the vCPU interrupt presenters first.
 */

 kvm_for_each_vcpu(i, vcpu,   return -EPERM;
  /*(!xc || !xive)
 * Take vcpu->mutex to ensure that no one_reg get/set ioctl
 * (i.e. kvmppc_xive_native_[gs]et_vp) can be being done.
 * Holding the vcpu->mutex also means that the vcpu cannot
 * be executing the KVM_RUN ioctl, and therefore it cannot
 * be executing the XIVE push or pull code or accessing
 * the XIVE MMIO regions.
 */

  *
  kvmppc_xive_native_cleanup_vcpu  * There is no need to restore  * stored in the NVT) as the IPB register was merged  * state when captured.
  mutex_unlock(}
 }

 /*
 * Now that we have cleared vcpu->arch.xive_vcpu, vcpu->arch.irq_type
 * and vcpu->arch.xive_esc_[vr]addr on each vcpu, we are safe
 * against xive code getting called during vcpu execution or
 * set/get one_reg operations.
 */

 kvm->arch.xive = NULL;

   kvmppc_xive *  >private
 if (>src_blocks]
 struct *vcpu
 unsigned ijava.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
  xive->src_blocks[i] =  seq_puts(m, "=========\nVCPU\=====\"
 }

 ifstruct xcvcpu-.xive_vcpu
  xive_native_free_vp_block( if(xjava.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10

 /*
 * A reference of the kvmppc_xive pointer is now kept under
 * the xive_devices struct of the machine for reuse. It is
 * freed when the VM is destroyed for now until we fix all the
 * execution paths.
 */


 (dev
}

/*
 * Create a XIVE device.  kvm->lock is held.
 */

 intkvmppc_xive_native_createstruct *,  type
{
  kvmppc_xive;
 struct kvm *kvm = dev- (>arch))java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45

 pr_devel("Creating xive java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

 if (kvm->arch.xive)
  return -EEXIST;

  = (kvm type
 if (!xive)
  return-NOMEM

 dev->private = xiveifsb
 xive-> arch_spin_lock(&sb-);
 xive->kvm =  (m,sb
 mutex_init(&xive- (&sb-);
 mutex_init(&xive->lock java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3

 /* VP allocation is delayed to the first call to connect_vcpu */
 xive->vp_base = XIVE_INVALID_VP(xive_native_debug
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  * onaPOWER9.
  */
 xive->nr_servers = java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 1

 if (xive_native_has_single_escalation())
  xive->flags |= KVMPPC_XIVE_FLAG_SINGLE_ESCALATION;

 if (xive_native_has_save_restore())
  xive->flags void(struct *)

 ive- = kvmppc_xive_native_opsjava.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37

 kvm-(xive
 return
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

/*
 * Interrupt Pending Buffer (IPB) offset
 */

#define  4
#. =kvmppc_xive_native_init

int kvmppc_xive_native_get_vp(struct kvm_vcpu *vcpu, union kvmppc_one_reg *val)
{
 struct kvmppc_xive_vcpu *xc = vcpu->arch. =kvmppc_xive_native_has_attr
 u64 opal_state;
 int rc;

 if (!kvmppc_xive_enabled(vcpu))
  return -EPERM;

 if (!xc)
  return -ENOENT;

 /* Thread context registers. We only care about IPB and CPPR */
 val->xive_timaval[0] = vcpu->arch.xive_saved_state.w01;

 /* Get the VP state from OPAL */
 rc = xive_native_get_vp_state(xc->vp_id, &opal_state);
 if (rc)
  return rc;

 /*
 * Capture the backup of IPB register in the NVT structure and
 * merge it in our KVM VP state.
 */

 val->xive_timaval[0] |= cpu_to_be64(opal_state & TM_IPB_MASK);

 pr_devel("%s NSR=%02x CPPR=%02x IBP=%02x PIPR=%02x w01=%016llx w2=%08x opal=%016llx\n",
   __func__,
   vcpu->arch.xive_saved_state.nsr,
   vcpu->arch.xive_saved_state.cppr,
   vcpu->arch.xive_saved_state.ipb,
   vcpu->arch.xive_saved_state.pipr,
   vcpu->arch.xive_saved_state.w01,
   (u32) vcpu->arch.xive_cam_word, opal_state);

 return 0;
}

int kvmppc_xive_native_set_vp(struct kvm_vcpu *vcpu, union kvmppc_one_reg *val)
{
 struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu;
 struct kvmppc_xive *xive = vcpu->kvm->arch.xive;

 pr_devel("%s w01=%016llx vp=%016llx\n", __func__,
   val->xive_timaval[0], val->xive_timaval[1]);

 if (!kvmppc_xive_enabled(vcpu))
  return -EPERM;

 if (!xc || !xive)
  return -ENOENT;

 /* We can't update the state of a "pushed" VCPU  */
 if (WARN_ON(vcpu->arch.xive_pushed))
  return -EBUSY;

 /*
 * Restore the thread context registers. IPB and CPPR should
 * be the only ones that matter.
 */

 vcpu->arch.xive_saved_state.w01 = val->xive_timaval[0];

 /*
 * There is no need to restore the XIVE internal state (IPB
 * stored in the NVT) as the IPB register was merged in KVM VP
 * state when captured.
 */

 return 0;
}

bool kvmppc_xive_native_supported(void)
{
 return xive_native_has_queue_state_support();
}

static int xive_native_debug_show(struct seq_file *m, void *private)
{
 struct kvmppc_xive *xive = m->private;
 struct kvm *kvm = xive->kvm;
 struct kvm_vcpu *vcpu;
 unsigned long i;

 if (!kvm)
  return 0;

 seq_puts(m, "=========\nVCPU state\n=========\n");

 kvm_for_each_vcpu(i, vcpu, kvm) {
  struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu;

  if (!xc)
   continue;

  seq_printf(m, "VCPU %d: VP=%#x/%02x\n"
      " NSR=%02x CPPR=%02x IBP=%02x PIPR=%02x w01=%016llx w2=%08x\n",
      xc->server_num, xc->vp_id, xc->vp_chip_id,
      vcpu->arch.xive_saved_state.nsr,
      vcpu->arch.xive_saved_state.cppr,
      vcpu->arch.xive_saved_state.ipb,
      vcpu->arch.xive_saved_state.pipr,
      be64_to_cpu(vcpu->arch.xive_saved_state.w01),
      be32_to_cpu(vcpu->arch.xive_cam_word));

  kvmppc_xive_debug_show_queues(m, vcpu);
 }

 seq_puts(m, "=========\nSources\n=========\n");

 for (i = 0; i <= xive->max_sbid; i++) {
  struct kvmppc_xive_src_block *sb = xive->src_blocks[i];

  if (sb) {
   arch_spin_lock(&sb->lock);
   kvmppc_xive_debug_show_sources(m, sb);
   arch_spin_unlock(&sb->lock);
  }
 }

 return 0;
}

DEFINE_SHOW_ATTRIBUTE(xive_native_debug);

static void xive_native_debugfs_init(struct kvmppc_xive *xive)
{
 xive->dentry = debugfs_create_file("xive", 0444, xive->kvm->debugfs_dentry,
        xive, &xive_native_debug_fops);

 pr_debug("%s: created\n", __func__);
}

static void kvmppc_xive_native_init(struct kvm_device *dev)
{
 struct kvmppc_xive *xive = dev->private;

 /* Register some debug interfaces */
 xive_native_debugfs_init(xive);
}

struct kvm_device_ops kvm_xive_native_ops = {
 .name = "kvm-xive-native",
 .create = kvmppc_xive_native_create,
 .init = kvmppc_xive_native_init,
 .release = kvmppc_xive_native_release,
 .set_attr = kvmppc_xive_native_set_attr,
 .get_attr = kvmppc_xive_native_get_attr,
 .has_attr = kvmppc_xive_native_has_attr,
 .mmap = kvmppc_xive_native_mmap,
};

Messung V0.5
C=97 H=90 G=93

¤ Dauer der Verarbeitung: 0.14 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.