linux/drivers/xen/pcpu.c
<<
>>
Prefs
   1/******************************************************************************
   2 * pcpu.c
   3 * Management physical cpu in dom0, get pcpu info and provide sys interface
   4 *
   5 * Copyright (c) 2012 Intel Corporation
   6 * Author: Liu, Jinsong <jinsong.liu@intel.com>
   7 * Author: Jiang, Yunhong <yunhong.jiang@intel.com>
   8 *
   9 * This program is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU General Public License version 2
  11 * as published by the Free Software Foundation; or, when distributed
  12 * separately from the Linux kernel or incorporated into other
  13 * software packages, subject to the following license:
  14 *
  15 * Permission is hereby granted, free of charge, to any person obtaining a copy
  16 * of this source file (the "Software"), to deal in the Software without
  17 * restriction, including without limitation the rights to use, copy, modify,
  18 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
  19 * and to permit persons to whom the Software is furnished to do so, subject to
  20 * the following conditions:
  21 *
  22 * The above copyright notice and this permission notice shall be included in
  23 * all copies or substantial portions of the Software.
  24 *
  25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  28 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  29 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  30 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  31 * IN THE SOFTWARE.
  32 */
  33
  34#include <linux/interrupt.h>
  35#include <linux/spinlock.h>
  36#include <linux/cpu.h>
  37#include <linux/stat.h>
  38#include <linux/capability.h>
  39
  40#include <xen/xen.h>
  41#include <xen/xenbus.h>
  42#include <xen/events.h>
  43#include <xen/interface/platform.h>
  44#include <asm/xen/hypervisor.h>
  45#include <asm/xen/hypercall.h>
  46
  47#define XEN_PCPU "xen_cpu: "
  48
  49/*
  50 * @cpu_id: Xen physical cpu logic number
  51 * @flags: Xen physical cpu status flag
  52 * - XEN_PCPU_FLAGS_ONLINE: cpu is online
  53 * - XEN_PCPU_FLAGS_INVALID: cpu is not present
  54 */
  55struct pcpu {
  56        struct list_head list;
  57        struct device dev;
  58        uint32_t cpu_id;
  59        uint32_t flags;
  60};
  61
  62static struct bus_type xen_pcpu_subsys = {
  63        .name = "xen_cpu",
  64        .dev_name = "xen_cpu",
  65};
  66
  67static DEFINE_MUTEX(xen_pcpu_lock);
  68
  69static LIST_HEAD(xen_pcpus);
  70
  71static int xen_pcpu_down(uint32_t cpu_id)
  72{
  73        struct xen_platform_op op = {
  74                .cmd                    = XENPF_cpu_offline,
  75                .interface_version      = XENPF_INTERFACE_VERSION,
  76                .u.cpu_ol.cpuid         = cpu_id,
  77        };
  78
  79        return HYPERVISOR_dom0_op(&op);
  80}
  81
  82static int xen_pcpu_up(uint32_t cpu_id)
  83{
  84        struct xen_platform_op op = {
  85                .cmd                    = XENPF_cpu_online,
  86                .interface_version      = XENPF_INTERFACE_VERSION,
  87                .u.cpu_ol.cpuid         = cpu_id,
  88        };
  89
  90        return HYPERVISOR_dom0_op(&op);
  91}
  92
  93static ssize_t show_online(struct device *dev,
  94                           struct device_attribute *attr,
  95                           char *buf)
  96{
  97        struct pcpu *cpu = container_of(dev, struct pcpu, dev);
  98
  99        return sprintf(buf, "%u\n", !!(cpu->flags & XEN_PCPU_FLAGS_ONLINE));
 100}
 101
 102static ssize_t __ref store_online(struct device *dev,
 103                                  struct device_attribute *attr,
 104                                  const char *buf, size_t count)
 105{
 106        struct pcpu *pcpu = container_of(dev, struct pcpu, dev);
 107        unsigned long long val;
 108        ssize_t ret;
 109
 110        if (!capable(CAP_SYS_ADMIN))
 111                return -EPERM;
 112
 113        if (kstrtoull(buf, 0, &val) < 0)
 114                return -EINVAL;
 115
 116        switch (val) {
 117        case 0:
 118                ret = xen_pcpu_down(pcpu->cpu_id);
 119                break;
 120        case 1:
 121                ret = xen_pcpu_up(pcpu->cpu_id);
 122                break;
 123        default:
 124                ret = -EINVAL;
 125        }
 126
 127        if (ret >= 0)
 128                ret = count;
 129        return ret;
 130}
 131static DEVICE_ATTR(online, S_IRUGO | S_IWUSR, show_online, store_online);
 132
 133static bool xen_pcpu_online(uint32_t flags)
 134{
 135        return !!(flags & XEN_PCPU_FLAGS_ONLINE);
 136}
 137
 138static void pcpu_online_status(struct xenpf_pcpuinfo *info,
 139                               struct pcpu *pcpu)
 140{
 141        if (xen_pcpu_online(info->flags) &&
 142           a>;
xen_pcpu_online(  77        };
  49  46
  46
  71static int   55struct   49  46
 142           a>n !!(buf)
f="+code=buf" clolass=_uclassf">buf, 0, &olass=_uclassvers/ref="drivers/xen/pcpame="L49">  49  467" id="L107" class="line"href="+code=cpu_&olaf">buf, 0, &olae);
 136}
info->flags) &&
 142           a>vers/xen/XEN_PCPU" class="sref">X1EN_PC14  77        };
  49  46
  46
  55struct 
pcpEINVAL" class="ame="L49">  49  46
 142           aomment"> 1* @cpu_id: Xen physical 1cpu l150ass="sref">buf)
f="+code=buf" clolass=_uclassf">buf, 0, &olass=_uclassvers/ref="drivers/xen/pcpame="L49">  49  467" id="L107" class="line"href="+code=cpu_&olaf">buf, 0, &olae);
 136}
 1* @flags: Xen physical c1pu st15f">xen_pcpu_oname="L137"> 137
 1* - XEN_PCPU_FLAGS_ONLIN1E: cp1 is onname="L137"> 137
  34#include <<1omment"> 1*/
pcpu)
pcpu)
href="+code=flags" class="sref">flags)
  34#include <<1on !!(pcpu {
15ine" name="L106"> 106        stru list_head pcpu)
 136}
d15ne" name="L138"> 138static void f="+code=1uint32_t" class="sref">u1int321t   49);
  46
u1int3215cpu" class="sref">pcpnline(cpu_id);
  34#include <<1ivers/xen1/pcpu.c#L61" id="L61" cl1ass="160ass="sref">buf)








rivers/xen/pcpu.c#L13040" id="L140" class="line" name="L136"> 136}
xen_pcpu_oname="L137"> 137
16ne" name="L133"> 133static name1 1  136}
 1=dev_name" class="sref">1dev_n1mename="L137"> 137
 116        switers/xen/p1cpu.c#L67" id="L67" clas1s="li1e" nam>pcpu_online_status(struct         uct  *dev,
  34#include <<1ivers/xen/EFINE_MUTEX" class="sref1">DEF1NE_MUT>  46
pcpu)
(dev, struct pcpu, dev);
 107        unsi="+code=L1IST_HEAD" class="sref">L1IST_H16ne" name="L110"> 110        if (ers/xen/p1cpu.c#L71" id="L71" clas1s="li170/a> xen_pa hredeavers/ref="drivers/xen/pcpame="L49">  49  467" id="L57" class="line" na6name="L107"> 107        unsihref="+co1de=xen_pcpu_down" class=1"sref171/a> buf, 0, &ef="vers/xen9/s="line" name="L49">  49 107        unsiha href="1pcpu.c#L73" id="L73" cla1ss="l17is onname="L137"> 137
  34#include <<1  .cm174 nam>pcpu_online_status(strunreginepcpu)
pf_pcpuinfo *pcpu)
 140{
 106        stru  .u dev,
 107        unsihmment"> *  restriction, including w>DEF17ne" name="L138"> 138static void ers/xen/p1cpu.c#L79" id="L79" clas1s="li178ist_headef="+code=CAP_SYS_AD40" id="L140" class="line" name="L140"> 140{
pcpriversname="L107"> 107        unsivers/xen/1pcpu.c#L81" id="L81" cla1ss="l18" name="L71">  71static int (ref="drivers/xen/pcpame="L49">  49  467" id="L107" class="line"name="L107"> 107        unsiva href="1de=xen_pcpu_up" class="s1ref">182ist_headef="name="L46">  467" id="L107" class="line"ss2" name="L46">  468" id="L88" classne" na e="L34">  34#include <<1vers/xen/1pcpu.c#L84" id="L84" cla1ss="l18a hr="drivers/xen33p"#="+code=list" "sref"dev,
pcpu, ,="li"L77">  77        an>,="li"L77">  cla6name="L107"> 107        unsi  107        unsi  .cm1          oL50" id="L50" class="liLers/ remove would"L23"mplicitly a hr"line" name="L55">  55struct int#="+code=list" "sref"dev,
pcpu,  107        unsi mment"> *f="+code=u" class="sref"1>u 137
  99        return1ers/xen/p1cpu.c#L90" id="L90" clas1s="li18D((  49 *pcpu)
 140{
 141        if (vers/xen/1pcpu.c#L92" id="L92" cla1ss="l191ist_head dev,
 107        unsiers/xen/p1cpu.c#L93" id="L93" clas1s="li192ist_heade((rivers/xen/pcpu.c#L125" id="L125" class="line" name="L125"> 125        }
ssi1ze_t<19" name="L34">  34#include <<1         1    struct  140{
buf)
rivers/xen/pcpu.c#L130era>dev,
 125        }
 127        if ( pcp1 *(ref="drivers/xen/pcpame="L49">  49  467" id="L107" class="line"name="L107"> 107        unsiers/xen/p1cpu.c#L99" id="L99" clas1s="li19   46bc#L70" id="L70" cbusne" a>(ref="drivers/xen/pcpxf="drivers/xen/pcpu.c#L63" id="L63" class="line"name="L107"> 107        unsiemment"> *  and to permit persons to="li19   468" id="L88" classne" naa>(cpu_id);
 107        uns2rivers/xe2/pcpu.c#L101" id="L101" 2lass=200/a>   46releas  77        releas pf_pa>(        uct  107        uns2rmment"> *pcpu.c#L102" id="L102" c2ass="2ine" name="L102"> 102static ss2ze_t<202/a> dev,
(#="+code=list" "sref"dev,
pcpu,  107        uns2         2            struct dev,
  46
pcpu,  107        uns2 5       2    char *buf)
rivers/xen/pcpu.c#L130era>dev,
 125        }
<2ct pcp2 * 137
 138static void2ref="+cod2=ssize_t" class="sref">s2ize_t2/a>   50al
ri clac24" ine" name="L21">  21ca21ic number
  21 *<

  24  55struct k2trtoull(  468" id="L88" classne" na ">  46
EINVAL;
dev,
(#="+code=list" "sref"dev,
pcpu, ,="li"L77">  77        an>,="li"L77">  cla6name="L107"> 107        uns2ivers/xen2pcpu.c#L116" id="L116" c2ass="21lass="sref">buf)
 href="+code=buf" cera>dev,
  46
val2/a>) {
EINVAL;
dev,
pcpu,  107        uns2 0:
 125        }
<2    ret2/a> =  137
 137
  71static int ret2/a> =  125        }
<2    break2
 137
  34#include <<2    ret22pcpu.e pcpu)
  49 *info,
 140{
 106        str2ivers/xen2pcpu.c#L127" id="L127" c2ass="22list_head pcpu)
 136}
r2t2>= 0)
 136}
ret22" name="L99">  99        return2rn flags) &&
);
);
 140{
buf)
rivers/xen/pcpu.c#L130ERR_Pss="sref">onlineonline 107        uns2ef="+code2DEVICE_ATTR" class="sref2>DEVI23ne" name="L102"> 102static ( *pcpu)
 107        uns2elt:
bool<2a> ( 140{
EINVAL;
online 107        uns2ehref="dr2ref="+code=flags" class=2sref"23ne" name="L116"> 116        swi2rivers/xe2/pcpu.c#L137" id="L137" 2lass=23ss="sref">int#="+code=list" INIT_pus" class="sref">xen_pcINIT_pus" claspf_pcref="drivers/xen/pcpame="L49">  49  467" id="L57" class="line" na6name="L107"> 107        uns2ivers/xen2pcpu.c#L138" id="L138" c2ass="23/a> *cpu_id);
(flags) &&
 136}
 cpu_id);
(flags) &&
  60};
 110        if 2rivers/xe2/pcpu.c#L141" id="L141" 2lass=240/a>   55struct xen_pa hreadd_taiapf_pcref="drivers/xen/pcpame="L49">  49  467" id="L57" class="line" na href="drivers/xen/pcpn/pcpu.c#L70" id="L70" class="line" n6name="L107"> 107        uns2>;
 133static   71stat2c int2dev,
(#="+code=list" regine  49 107        uns2>ivers/xe2ambig=include/asm-alpha/2xen/h24e_attribute" ef="f="+code=buf" cera>dev,
  46
buf)
f="+code=buf" cpr_warnass=d="L140" class=r_warnasspf_pccode=CAP_SYS_ADuot;xen_cpu: "
->ivers/xe2cpu.c#L47" id="L47" clas2s="li24a>) {
EINVAL;
)
f="+code=buf" c="sref">flags) &&
 107        uns2>vers/xen2XEN_PCPU" class="sref">X2EN_PC24online 107        uns2>a href="2cpu.c#L49" id="L49" clas2s="li24a> =  137
 110        if 2omment"> 2* @cpu_id: Xen physical 2cpu l25s="sref">HYPERVISOR_dom0_op(&am40" id="L140" class="line" name="L136"> 136}
 2* @flags: Xen physical c2pu st25e" name="L92">  92
 2* - XEN_PCPU_FLAGS_ONLIN2E: cp25ne" name="L133"> 133static   50 2*/
  50pcpu {
25ine" line
  55struct pcpu_oe(  49flags)
flags)
 140{
d25E_MUT>  46
u2int322t ( 130}
u2int3225cpu" class="s pcpu)
( 136}
bpuinfo *info,
 136}
 2cpu.c#L62" id="L62" clas2s="li261ist_head op = {
  85              2263" id="L123" class="l  = XENPF_cpu_F_INTERFACE_VERSIONget_fo" class="sref">infoget_fo" cla" na e="L85">  85              2name2 26a hr="drivers/xen33p"ersion      = XENF_INTERFACE_VERSION,
  87              2emment"> 2=dev_name" class="sref">2dev_n26/a>                    = info  87              2en !!( 136}
 127        if 2ivers/xen2EFINE_MUTEX" class="sref2">DEF26/a> *count;
op);
  91}
count;
 140{
L2IST_H26cpu" class="sref">pcpriversa href="+code=uireid="L130" class="line" name="L130"> 130}
  71static int  (ref="drivers/xen/pcpid="L91" class="line" n  = info 130}
  46max_.c#2" id="L122" clmax_.c#ne" name="L140"> 140{
(flags) &&
buf, 0, max_presass="+cname="L130"> 130}
 2f="+code=cmd" class="sre2f">cm27sref"ame="L107"> 107        uns2  . (pcpu)
href="+code=flags" cc#L2" id="L122" class" naame="L91">  91}
u 127        if 2hmment"> 2  restriction, including2w>DEF27/a> *  50  24  55struct flags) &&
);
);
  85              2ers/xen/p2cpu.c#L82" id="L82" clas2s="li28a> = cpu_id);
 140{
283" id="L123" class="lpcpu)
pf_pccode=CAP_SYS_AD40" id="L140" class="line" nname="L107"> 107        uns2vers/xen/2pcpu.c#L84" id="L84" cla2ss="l28a hr="drivers/xen33p"rivers/0name="L125"> 125        }
<2           me="L92">  92
cm28ne" name="L116"> 116        swi2  .int hre+code=CAP_SYS_AD40" id="L140" class="line" name="L85">  85              2emment"> 2f="+code=u" class="sref"2>u(  49flags) &&amnname="L107"> 107        uns2vrs/xen/p2vers/xen/pcpu.c#L89" id=2"L89"28a> =  140{
pcpu *online 107        uns2 ( 107        uns2 rs/xen/p2pcpu.c#L92" id="L92" cla2ss="l29a> = xenpf_pcf="+code=buf" c="sref">flags) &&am hcode=CAP_SYS_AD40" id="L140" class="line" nname="L107"> 107        uns2ers/xen/p2cpu.c#L93" id="L93" clas2s="li29ne" name="L133"> 133static ssi2ze_t<29 125        }
<2         2    struct  137
 116        swi2= .  50pcp2 *line
  50  55struct  2  and to permit persons 2o="li29D(( 140{
 141        if 3rmment"> 3pcpu.c#L102" id="L102" c3ass="301/a>   50ss3ze_t<30is online
( x" ne" name="L50">  50ssi3f="+c30" namcL50" id="L50" class="rEEEEEEEE*ine" name="L55">  55struct flags)
(0 hcode=CAP_SYS_ADmax_.c#2" id="L122" clmax_.c#ne" E>(0name="L125"> 125        }
<3 5       3    char *be((0name="L125"> 125        }
<3 6       3 cpu.c#L97" id="L97" cla3">pcp3 *pcpu = container_of 107        uns3gned long3long  138static void3ref="+cod3=ssize_t" class="sref">s3ize_t3/a> op = {
 107        uns3ivers/xen3pcpu.c#L110" id="L110" c3ass="3ine" name="L110"> 110        if 3mivers/xe3+code=capable" class="sr3f">ca3able(dev,
((  85              3mmment"> 3<
EPERM;
( href="+code=uisync ame="L49">  49 107        uns3ivers/xen3pcpu.c#L113" id="L113" c3ass="313" id="L123" class="lcode=CAP_SYS_AD.c#2" id="L122" class" na++name="L107"> 107        uns3i3="+code3code=kstrtoull" class="s3ef">k3trtoull( 137
 107        uns3ivers/xen3pcpu.c#L116" id="L116" c3ass="31lass="sref">bef="f="+code=buf" cera>dev,
 107        uns3i6       3f="+code=val" class="sre3">val3/a>) {
EINVALdev,
);
 107        uns3ined long3f="drivers/xen/pcpu.c#L138" id31pcpu)
pf_pccode=CAP_SYS_AD40" id="L140" class="line" nname="L107"> 107        uns3    ret31" name="L99">  99        return3    break3
op = {
 107        uns3 1:
  71static int ret3/a> = dev,
 107        uns3 vers/xen3
 137
  34#include <<3    ret32pcpu.e (str= {
 107        uns3 href="dr3vers/xen/pcpu.c#L126" id3"L12632ine" name="L106"> 106        str3ivers/xen3pcpu.c#L127" id="L127" c3ass="32ss="sref">int#="+code=list" x65"sync ame=#L70" id="L70" classsync ame=#pf_pcnname="L107"> 107        uns3 ned long3code=ret" class="sref">r3t32 137
ret32sref">pcpu_o#="+code=list" DECLARE_WORKL70" id="L70" cDECLARE_WORKpf_pccode=CAP_SYS_AD= {
);
 107        uns3    break3="+code=ret" class="sref3>ret<32ne" name="L110"> 110        if 3rivers/xe3/pcpu.c#L131" id="L131" 3lass=330ass=>pcpu_o#="+code=list" irqriverssref">flags)
irqriverssr"drivers/xen/pcpu.c#= {
flags)
= {
flags)
irqe" n>)nlinee=container_of" an>,122" id="L122" clan>,12" na6ame="L107"> 107        uns3ef="+code3DEVICE_ATTR" class="sref3>DEVI33ne" nname="L106"> 106        str3ivers/xen3pcpu.c#L133" id="L133" c3ass="332/a>  107        uns3elt:
bool<3a> xen_pcIRQ_HANDLEsne" name="L107"> 107        uns3rivers/xe3/pcpu.c#L135" id="L135" 3lass=33ename="L137"> 137
 116        swi3rivers/xe3/pcpu.c#L137" id="L137" 3lass=33" nam>pcpu_oe(flags)
_=_Vir"drivers/xen/pcpu.c#= {
flags)
= {
 140{
 (flags)
irqe" n>) href="+code=uireid="L130" class="line" name="L130"> 130}
 110        if 3rivers/xe3/pcpu.c#L141" id="L141" 3lass=34ble( 140{
EPERM;
online 107        uns3>;
 133static   71stat3c int3flags)
irqe" na>( href="+code=uibinddev,
dev,
)0 e="L87">  87              3>ivers/xe3ambig=include/asm-alpha/3xen/h34a> = -)
a>)
"+code=cpu_id" = {
flags)
= {
)0 e="L87">  87              3>href="dr3ambig=include/asm-alpha/3xen/h34lass="sref">buf)
="+code=cpu_ola>)
a>)
"rivers/xen/pcpu.c#L48" id=   -    > 107        uns3>ivers/xe3cpu.c#L47" id="L47" clas3s="li34ss="sref">int hre"+code=cpu_id" irqef">flags)
irqe" naline 0name="L85">  85              3>vers/xen3XEN_PCPU" class="sref">X3EN_PC34
-> 107        uns3>a href="3cpu.c#L49" id="L49" clas3s="li34a> = flags)
irqe" nname="L107"> 107        uns3>        3*
 137
 3* @cpu_id: Xen physical 3cpu l35" name="L71">  71static int  3* @flags: Xen physical c3pu st351/a> count;
dev,
 107        uns3omment"> 3* - XEN_PCPU_FLAGS_ONLIN3E: cp352ist_headef="name="L46">  46ef">count;
  85              3oiversine3* - XEN_PCPU_FLAGS_INVAL3ID: c35a hr="drivers/xen33p"#="+code=list" 4r_warnass=d="L140" class=r_warnasspf_pccode=CAP_SYS_ADuot;xen_cpu: "
 107        uns3omment"> 3*/
 107        uns3on !!(pcpu {
355" id="L120" name="L137"> 137
 127        if 3overs/xen3"+code=device" class="sr3ef">d35/a> *count;
 107        uns3f="+code=3uint32_t" class="sref">u3int32358ist_headef=""+code=cpu_id" ef">count;
  85              3o        3uint32_t" class="sref">u3int3235cpu" class="sref">pcp#="+code=list" 4r_warnass=d="L140" class=r_warnasspf_pccode=CAP_SYS_ADuot;xen_cpu: "
-> 107        uns3ivers/xen3/pcpu.c#L61" id="L61" cl3ass="360ass="sref">buf)
goto f="+code=buf" cera2cpu: " 107        uns3imment"> 3cpu.c#L62" id="L62" clas3s="li36f">xen_pcpu_oname="L137"> 137
36ne" name="L133"> 133static name3 3  125        }
<3emment"> 3=dev_name" class="sref">3dev_n36sref"ame="L107"> 107        uns3en !!( 107        uns3eivers/xe3cpu.c#L67" id="L67" clas3s="li36ss="sref">int#="+code=list" busdev,
 107        uns3ivers/xen3EFINE_MUTEX" class="sref3">DEF36/a> *f="+code=buf" cera1cpu: " 107        uns3e="+code=3cpu.c#L69" id="L69" clas3s="li36a> dev,
flags)
irqe" n>) href="+code=uiNUL5" id="L125" claNUL5ne" nname="L107"> 107        uns3="+code=L3IST_HEAD" class="sref">L3IST_H36cpu" class="sriversa href="+code=uireid="L130" class="line" name="L130"> 130}
 137
  href="+code=uiarch
_Vir idld="L130" class=arch
_Vir idlpf_pccode=CAP_SYS_AD= {
flags)
= {
 107        uns3ea href="3pcpu.c#L73" id="L73" cla3ss="l372ist_


> The original LXR software by 24" me="L107"http://sourceforge.net/projects/lxa>>LXR " cluVirye" n>)tdrivexperilassal class=" by me="L107"maiato:lxa@ idux.no">lxa@ idux.noe" n.
> lxa. idux.no kindly honeRedpill Lidpro ASe" n>)provida>as= Liduxref=sult.c#cref=opera24" iEserviceiEsincei19<5.