summaryrefslogtreecommitdiff
path: root/arch/riscv/kvm/vcpu_sbi_sta.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/riscv/kvm/vcpu_sbi_sta.c')
-rw-r--r--arch/riscv/kvm/vcpu_sbi_sta.c208
1 files changed, 208 insertions, 0 deletions
diff --git a/arch/riscv/kvm/vcpu_sbi_sta.c b/arch/riscv/kvm/vcpu_sbi_sta.c
new file mode 100644
index 000000000000..01f09fe8c3b0
--- /dev/null
+++ b/arch/riscv/kvm/vcpu_sbi_sta.c
@@ -0,0 +1,208 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023 Ventana Micro Systems Inc.
+ */
+
+#include <linux/kconfig.h>
+#include <linux/kernel.h>
+#include <linux/kvm_host.h>
+#include <linux/mm.h>
+#include <linux/sizes.h>
+
+#include <asm/bug.h>
+#include <asm/current.h>
+#include <asm/kvm_vcpu_sbi.h>
+#include <asm/page.h>
+#include <asm/sbi.h>
+#include <asm/uaccess.h>
+
+void kvm_riscv_vcpu_sbi_sta_reset(struct kvm_vcpu *vcpu)
+{
+ vcpu->arch.sta.shmem = INVALID_GPA;
+ vcpu->arch.sta.last_steal = 0;
+}
+
+void kvm_riscv_vcpu_record_steal_time(struct kvm_vcpu *vcpu)
+{
+ gpa_t shmem = vcpu->arch.sta.shmem;
+ u64 last_steal = vcpu->arch.sta.last_steal;
+ u32 *sequence_ptr, sequence;
+ u64 *steal_ptr, steal;
+ unsigned long hva;
+ gfn_t gfn;
+
+ if (shmem == INVALID_GPA)
+ return;
+
+ /*
+ * shmem is 64-byte aligned (see the enforcement in
+ * kvm_sbi_sta_steal_time_set_shmem()) and the size of sbi_sta_struct
+ * is 64 bytes, so we know all its offsets are in the same page.
+ */
+ gfn = shmem >> PAGE_SHIFT;
+ hva = kvm_vcpu_gfn_to_hva(vcpu, gfn);
+
+ if (WARN_ON(kvm_is_error_hva(hva))) {
+ vcpu->arch.sta.shmem = INVALID_GPA;
+ return;
+ }
+
+ sequence_ptr = (u32 *)(hva + offset_in_page(shmem) +
+ offsetof(struct sbi_sta_struct, sequence));
+ steal_ptr = (u64 *)(hva + offset_in_page(shmem) +
+ offsetof(struct sbi_sta_struct, steal));
+
+ if (WARN_ON(get_user(sequence, sequence_ptr)))
+ return;
+
+ sequence = le32_to_cpu(sequence);
+ sequence += 1;
+
+ if (WARN_ON(put_user(cpu_to_le32(sequence), sequence_ptr)))
+ return;
+
+ if (!WARN_ON(get_user(steal, steal_ptr))) {
+ steal = le64_to_cpu(steal);
+ vcpu->arch.sta.last_steal = READ_ONCE(current->sched_info.run_delay);
+ steal += vcpu->arch.sta.last_steal - last_steal;
+ WARN_ON(put_user(cpu_to_le64(steal), steal_ptr));
+ }
+
+ sequence += 1;
+ WARN_ON(put_user(cpu_to_le32(sequence), sequence_ptr));
+
+ kvm_vcpu_mark_page_dirty(vcpu, gfn);
+}
+
+static int kvm_sbi_sta_steal_time_set_shmem(struct kvm_vcpu *vcpu)
+{
+ struct kvm_cpu_context *cp = &vcpu->arch.guest_context;
+ unsigned long shmem_phys_lo = cp->a0;
+ unsigned long shmem_phys_hi = cp->a1;
+ u32 flags = cp->a2;
+ struct sbi_sta_struct zero_sta = {0};
+ unsigned long hva;
+ bool writable;
+ gpa_t shmem;
+ int ret;
+
+ if (flags != 0)
+ return SBI_ERR_INVALID_PARAM;
+
+ if (shmem_phys_lo == SBI_STA_SHMEM_DISABLE &&
+ shmem_phys_hi == SBI_STA_SHMEM_DISABLE) {
+ vcpu->arch.sta.shmem = INVALID_GPA;
+ return 0;
+ }
+
+ if (shmem_phys_lo & (SZ_64 - 1))
+ return SBI_ERR_INVALID_PARAM;
+
+ shmem = shmem_phys_lo;
+
+ if (shmem_phys_hi != 0) {
+ if (IS_ENABLED(CONFIG_32BIT))
+ shmem |= ((gpa_t)shmem_phys_hi << 32);
+ else
+ return SBI_ERR_INVALID_ADDRESS;
+ }
+
+ hva = kvm_vcpu_gfn_to_hva_prot(vcpu, shmem >> PAGE_SHIFT, &writable);
+ if (kvm_is_error_hva(hva) || !writable)
+ return SBI_ERR_INVALID_ADDRESS;
+
+ ret = kvm_vcpu_write_guest(vcpu, shmem, &zero_sta, sizeof(zero_sta));
+ if (ret)
+ return SBI_ERR_FAILURE;
+
+ vcpu->arch.sta.shmem = shmem;
+ vcpu->arch.sta.last_steal = current->sched_info.run_delay;
+
+ return 0;
+}
+
+static int kvm_sbi_ext_sta_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
+ struct kvm_vcpu_sbi_return *retdata)
+{
+ struct kvm_cpu_context *cp = &vcpu->arch.guest_context;
+ unsigned long funcid = cp->a6;
+ int ret;
+
+ switch (funcid) {
+ case SBI_EXT_STA_STEAL_TIME_SET_SHMEM:
+ ret = kvm_sbi_sta_steal_time_set_shmem(vcpu);
+ break;
+ default:
+ ret = SBI_ERR_NOT_SUPPORTED;
+ break;
+ }
+
+ retdata->err_val = ret;
+
+ return 0;
+}
+
+static unsigned long kvm_sbi_ext_sta_probe(struct kvm_vcpu *vcpu)
+{
+ return !!sched_info_on();
+}
+
+const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_sta = {
+ .extid_start = SBI_EXT_STA,
+ .extid_end = SBI_EXT_STA,
+ .handler = kvm_sbi_ext_sta_handler,
+ .probe = kvm_sbi_ext_sta_probe,
+};
+
+int kvm_riscv_vcpu_get_reg_sbi_sta(struct kvm_vcpu *vcpu,
+ unsigned long reg_num,
+ unsigned long *reg_val)
+{
+ switch (reg_num) {
+ case KVM_REG_RISCV_SBI_STA_REG(shmem_lo):
+ *reg_val = (unsigned long)vcpu->arch.sta.shmem;
+ break;
+ case KVM_REG_RISCV_SBI_STA_REG(shmem_hi):
+ if (IS_ENABLED(CONFIG_32BIT))
+ *reg_val = upper_32_bits(vcpu->arch.sta.shmem);
+ else
+ *reg_val = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int kvm_riscv_vcpu_set_reg_sbi_sta(struct kvm_vcpu *vcpu,
+ unsigned long reg_num,
+ unsigned long reg_val)
+{
+ switch (reg_num) {
+ case KVM_REG_RISCV_SBI_STA_REG(shmem_lo):
+ if (IS_ENABLED(CONFIG_32BIT)) {
+ gpa_t hi = upper_32_bits(vcpu->arch.sta.shmem);
+
+ vcpu->arch.sta.shmem = reg_val;
+ vcpu->arch.sta.shmem |= hi << 32;
+ } else {
+ vcpu->arch.sta.shmem = reg_val;
+ }
+ break;
+ case KVM_REG_RISCV_SBI_STA_REG(shmem_hi):
+ if (IS_ENABLED(CONFIG_32BIT)) {
+ gpa_t lo = lower_32_bits(vcpu->arch.sta.shmem);
+
+ vcpu->arch.sta.shmem = ((gpa_t)reg_val << 32);
+ vcpu->arch.sta.shmem |= lo;
+ } else if (reg_val != 0) {
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
- 3jwC&H-Zp0q>_H$>?UT.;Zay![jVn qRA;7+If}R[MUGX;JN RΟ2*`} 5f+FN "c.-)DtcH %)ѧqxZ϶X,H3r[pƎDoL\꠽@|t˽ a1W~6SWideϽ$ 4ְ(:8(ZL5(f?u+ =#S{OfMoϞ= &˗~o^&Iߨ|\x"M^_^3 ۦ]U-czI4Q_3~N&pң4Ҹ3=#|qz,'{FьiQ}yc#Fg9U]N2#j,|PtZ/9luMS{l7C勧P"[Aqm䏳rsTom~w@K=i#h[ 8%RjxeyDj9"N ?>쀽uTOhǁr|\n#ɌZࡣ~ƛhڭQ;瀻VDБ5R3! u;h`ϛa~YG4z BR/d .}/O*RY)N?/_nS?nM+gWoE&! htV*C7o['_׮SZ[K_WF]}zY& a*D*Xw;ZIJDmr;Vހ'!\ZOn3]_vN9ZӼ!-&(.J?5K"ȗ^ӊKˎjWJfE#k:Us!OE;L;,(=v`;QT'Ws"#7oHN}@"mĤDƛ7CzxR]&Z܇1%˯~o)(xJKtr?Mooe XY $k.MI>8b`9zٷ7e#fQi< 4q+<*dIAxV T_8M°$ICx]d!^RW #'ۊbJOβJwenNZQ]MkhB2EŜnx1~ȧKVrbxC=HLT wL=y'P,{3IAxf7n@@ٙZ|c1:A^ŹCﰵsb}E];z"tV2/m(r#V MA{S'ԇ?F,~RVc$Dvv1os:Oehm=DG|SWTW!bt11v+n|?m~՞ m`ܐq=xnMNE-=CMh"jG?ZQW,l ,/٣KY%D8forf K_;iʝԋV<" ">fW̿ĕFԶk(ugJ>y (9.+aoqE In59$VPb(߆Ă'UtN>FQ{7}$vPa;<49y۸|ؗo2! $#Y/#{òiarY }mNW4d2~=|쏠'/5]m55Tsc$| eؖlĨ ;=4 ώ ?XإgDhz?NpuzOMLMJHܴ9TөմZ-5W!>" 5Igi& T]VKxO@' ϫ6͢i?fw!EtԚI_ow9TjлjښLUY7{ ՞GjNP8oA 2۪#u 4,5Tna0_StHj'=l7m~AG:KY|ͣK>VZN_)Țj=Ҷɀ)<8떵zO%v1mbL L1W/M~K$t3nH>/Qبưߩwm5$mA5la&JSTu6Z|(Zeq}u8TPw0 xA;Xk瑌K1Eɀi#9#V4HXiPyK4aUm6oK tH% m%ӁR6ӎu!YejX&(LNoZMe6'}k۪oThI A<$P_ /R+@ܔN?9Ƀy#_*5T߆窽8iv'@3`⠨ 5K/Ke+})o7.QE%/6K58ِ oP{ϴl_Xcˈ֮6`flBРR8tBR*r* ! exDl\*ݢZk`6oi465j^*91ٰS46k_< ߩx IZ,cu{*sSQOJ#,TdN.,BЍ@l^]gN\E#UE_I)R7M1#(U5ڽj<\7hT<1=QXlx5i  -ڕu sjb0r01 #X.M,G+I$GEefTZ+_{PWBl@z^x_$clKNc_Ax|=|S 55[3,kgOIIUWam{ųi8Lo^M \᫱¾5%%%M%/|n;1lNYQ)ZU]rh;^W&?Uڲif ?I~\.'֫B ٵl-4 ;ZZIi#FC i$Q𫫗Mk}T=GW."|J,Deի|QkrTIMU&h}ٯ :(qm_uvA2 B^Y/cg z_) S5I>d^|HNx)GxIƮJҧ!#xwCzx{ƅ\x%]#1 @$W]v`q2?vffgb~Gdp'U{"几MDױKN}.|!%b⻴䱽Rk)2ɑUjǿ͏^'Ͷ Gj'Q&}Y,E"L=-+zHU݂۫v5.طh"2Eo!pM>{Z/'_S+zlvfY 3gỮmUweׄN1%exxO>աO;Gi8B-9^&[6HRV:~:%@Bri+7u;}6HӣC3豂χ!Uj7&ƒO_G'F+M5 Yhm>i&xčS"D#^A 4]UoSme42xr_ཱི?=E-͵資ް#"Z?jz5AjFlQ[5F Guph{ART#OU7 "@NCAAq[~~^}:RVfP&R6DMEg(:ٴ. G] d8;yH^.DD $hC{pƅ[GYc7>*_czNcإSj&&xŰRj 7 ZbO8(Y]AɆVC[][j,uɸ(6pHaZLd~pC<΋!IgZZx`tWjtLvq/sP%ずEg8Ϥ8upg&UTnIC־ `=//hZ>i5y~̽9=OU1t4K#35֮Y'ܑW"{C%<%1$XfD؀,U3} <~p-7"~$ctjz?_yC/2#7MRxEz#0/^!'|-hN3hg˵N⚺$\ kƓt).Vn>v s5^MqQ]ZɺvIqb!RLd+t%B4PE tjM{2&ds\ IA/^;QZO֑#9 aEz/|1oB1R4oE5eM 鞅zQ_:yP-H$~ %Tuk@a@"Q<1VWp6mխCj̖jLGZ\G-ERVX$v7P8t:Ufס4xy׹i%3_]u k$LnԿt\B;[0F!{hL$R\&25H''S Tf+ rem^ri7pgR)4 dZ<{%[r9L3 @~8r-|B:Hp' ֱx +'EqW79m6j]s:7i^1Rl]RW] p5Cfg]S 9^$Xd^µR'GpB;2~Z yNfSt fU{k.c` zFB-Kk^ qd/2{o#j5iPQCZ0&*8ŵFkrވžɆ@,p2[n2=,F2MZa;fɡ^0MSpii;u6w嬽p8xカ&Ӛ/尒i;k: OuǠi+ΆT,믯XU,tvF{;KӘ{sԙєT%К鎛>{ (B1e{g+y$i0Ff|5LɚK -ǯOE+&OZ'.n#)4Գ¢~@^Yo =t' =垯v$Z?)zդE`=wiOǴڍ3NPAJ t eGb{~o9+4?]YQ e)I ؚz_*+RgE6L.;g!}y"WeǜZ;Op]9.#f vw}0Sdos ~YEu%թA`͏'Jsb h42S%ϑIf~P$'e)Êz.o@"yhyd돷>Clgyi[7whxt@\ />kOl LḴF§M碌{ƀ.-wjvJZ;uyLRusScHO3t7zu-{tcNykQi1iotU;*s i6+m51 g(«>^+Im \6aHEoĨܛG_HPԻ%/"NwC -d`z,ө;X&0x+/W+_+8{J7K6C*iWmZx7 cNi i˂D`%J ~F99 ^[QѼ.WoK qlL"Xw h}صW5HˁF┌jr_ ,U&ZiԡU<TB1*W DylڀxH0sHy%6AQ%${ݗseSj땺}셱Rd_m>P_4USD;jHKVs~b}g@1pQ>PgE4UsDi|:*I4" tϲ{- 6N d_L&>##-B,OhCz/ B'צZ$: W 铀 pǦAKW4LD2cUۃ-E,I*g8[aDZP-!u2 d)M'~jK/Lqg27:j7լӛF?QN} @:SmP SyƑcGW_TłU!l$%-T J?xZ!wcr< ezͧ#sjrizr @H#D&;m/"Ih;:'UD9BqQ+;}wCxq$~Ʒ-hqNw~ROK8hEdw-@3pe{\]hіq5.11 @ +VpJuAjz(ԁE\&NCf~rWNВ'F1-I6I7LґMsMzUAy|PgeNJ# Lq S"Lb$ɪJyJ~ +{9ys8$DFޮѧ%&bg,;Snz@irI}MTwM՜ #z፻֘&> ";8 j|+)9=i7rn1EiO_>-a(2:]-XqOe !{r&)zh1G-I صI} +iXC,:0@M?qˉzvJ=)ƇPaJtilZFVJ6 > 곻)CD,!RS1ܷxE[5鈫 S݉O̱-ncRoMFJԑIϺvZiWuhniKzj :qե%"A0{gq+iO@;4J63%y]EyfCm(ZcV[rVdEA2S-^UIznp-Vp#nkMrny&ŵ \~2,P{ɒx=l4Iz4w 5~Zc4_hJ}GC"+ڀoO'Oni"{@ڠp=Pc,0w] 9b's8 э5&[ U,øZ1S =zΗ/_ J)RqwԠ_D=aW"U[0f2RSKqX^z2`6c$d阶 w'eհiGS%W(4x||Fʕo /+EH$/Ju{^W{7/B^ aH"Vc tOt ; X:|#ɓߓMfEzk1[[B>a+W+qekos ntђJ#VjJ ]hYLwq:ǀg.Lp5'@1 |z 8QWMtn@+F+gw:;R#b,B=H ڭsT@.84fjLF2AquC#4rdNz4-$ax;uLoׯ\2 v&aR%Ƨ)灓%\ ܠެu /$H6B?hYseNUH1U Cx桒d]VDF#{&f4?]0?HlNb0 l;&!:~8@VUr(3{&G2n{ ^H[hTb?`qGE~xu;fԈϖG_"Lr;6{ ds>YeUU $!G(xkpRd,-2v*4n\ j lFu7}hk~0y5lL,|I/%xS/Of0>h$ɉq|K}rCz ^;{[ə$L;KaW+4ZN^Y Wy8YK;ksr/rn|!4kI߬i>͚9E+\&Z{&isZT$.iA,eyY2//GH)',6X[Nֲ)5£f H @ѧ 0KjhGA+*qDYdSc%5L hGƝ$,6Y{oq_7>?[`Lݑ¨m-f OӂDnJZѪYjڤ4!0!'34y]ue$ݾhq?19ZB^2 R6z(> d:2IdMM@Dv;F$橽Q.2 .bwX낦IȘE#o‘꥾Qov!$V?t")h~ׂ0ez nGGڑM`H;u=A sqw7|M&D64 kM3a_,ps_ke3J{p2%H=ULbȬZcz,"Hz)~y)Qǣ ΥFI8gZOɓNJz4k̥<xp 1Z  f^g1^C=pxi> .M8-Ul.t ZHqv;Tƥ&9NZFEWG5,OJ1fAoRR4Zgdht-Y2MWלi}qw˧Wl窵Itr&_;:sҙ4kG69].;ڳ:j 'G>?Wi;2 VVz@ {;[M)ʭ! &fY\J@X&i#!T""s,7"2? [^ V +qƑ3k®^Dl/M2$hCd5pt^H>wHO"@]bEj1үuc*XСcӠXZL6p[¡ K$\G@pq>On٦vw4j! 25Kz#>(7) bBoFS\P8УJKܾ(K8aL8 *Vv\d8Lg(\˸CZtԧ+~hIOkTFv 'r¥6N"P6S jx7n%{W]| kPcUFَZg ֡FK)r% T۠~ Zzuw*n.56XaۀӎX=܌f織mM4 ǛP#mN\<K;`h'0?MfsHAS/Im 9iy3YCe=s6jLM2ըIK ;JRU0j7U: #:S6Ci=m2Xbf®A $™6SfRvՑ4}:f`Y^XhҰ1qYPJ!a,jd3zZw_?6JŃZV,_=My#KCfۤj7OĨ!SN$@YӮ`〦28 $) ;uduzi]؛;_!ny}BK \K0lvBXYyzݎ)l &oQgC`o&C5mk8TmxcjhhҙuA#k)v mkF[ "iB=QW+bͯ\/VQj79lvˈH ,z) E;d.0FA!VaN}GG ZTc {q^L뱿yl$a6Ui4Zjn}J(  ;YZߣP, ܯݩq8 \ZMޙѣx'šNVQ?π@ b}}0P*1+~OZtdSU-Lwi&I ,;k{b0b$}qFn譻Vս#C0UmE,0v~HVH7X2o]z3;,EttVxn% -_MՆfg[8^X.g,Ufe gyRWdctj'y:ǩJ+Yn֯, ,lSfxLmƯvZ ~G /$訉(t!f=#LRݿ(Se>~ٿAȥex;"F,vf  ,uc.{YZd@Z&4 b;SxɅ(EHZ *za}ܞL?1M`_'la,akEDu~f^=.BγV >p`A;@n1|8\8"E̍BeT*I_ebh׎qO;= dS тڢEX 5MT{XpJ1sglogA{WNԚ×`, (^8L .4C[+d^4Je4X} %XsO50HN[jAM6#qRLˍ1s,un%$qrF @)*Cl(v/b6m\k(oM;6sӥq`5 ':D)_)%r _79Yvp}\[[2.Zw_$ͬѬ7 ҇zz`R۫7dY8DC]R1Y5"})"bi8 #3Vi_)[iŖ"lV.Km&ó.tp-.׶G-% ЎCEuŬP5Vo uRQ~O Z?ѤKR[gFjwivr_.eEhN>T*)o!Ȁ;f(*,`:ef+3;M|F4=`H8_Z6,/Xr5S),R_KJy)Sˏ2vM*U*`u.GtH݆ *1 =Ҷ12@󪶸8[plk!嵭Lf.-jFX=R(3O%y8Otu:~Jv}`ֈ_Ts+7JZ{֧;x@kq#Szpd7}T!5FIXcXjGL lEjfW5J*uZ`Q]V> uÛ~*J]עe)q ȥ1{% AKм;4,NTJ I<"1쑤O`o$}H&jB$U2(zTYq܌.E~We&>+3;|WaK+8j7YewtX'U}5NNw~^a  Z K.-o V#j^pOjdš&꯶IvfW j8d\յԞި:r_}VL2ॵڣO8ë.C"~QJV&]jCC66 t9r *$B!(V'zvSC8J.,iqتd4fɩf\ ~m0챴tIz4J'a|\#IR s:ٌ"58Ҡ2XQQˎY=}Yt%Ƙˆܠ<<[(DH4K.QGAض](k29-U2ۜ\K<.R['u.sSt5"Yv 6N}+95 ФInuOW6IXs\#$6j< )aD'>ň 9juX}InhY9Arrj<~;Z 0Ƽ܄~cHW4lZGVJ~:58onfUU5艏^[W[n@*-wa'F&rq> bVIOsh 0m߾JꡯNI1p/yչγSUn߁XS%:jtg|^tjͦzz J_Gq B얩]=K'5Ő}yi*epܤtq=ձ[R8x H ?a;m >#5m^p 0)5JUdUg\NZqDq o鸩fT5lF {p)FM})& t`@կ&X'm3jUw3H1N-OAHh`,L!AX_}ryokf?h]EyJ!,H;spb%y,NdY8kHHdB Tk6m;\_˼nYݿz6)!t'wEe-2M6#%u:ѯ}*E F"f(ٴwtĒ:kE#7 MQ8% h z]*TEр1M">4e3`9漬x^6Hf t3ў{ZiOz.>"!?P0T58cY gi `҉_nKABc' 夔t"†=[ppS:aVtnt:Q66[veh%9}B:^bj =`*cVpKp5JSVTٞGDîqP7<$ZyR?&P(ifMV4WdOʮcG%znMӿ'>Xw6?ބlXڍDk,N8Pt*g K}jS";rsv{cֳ83O5Nc̀e V~lS}gش=:QCSEVb#3dgg[k=#$XAeO']:['0'6Yי m|I}́sFw~k- rnF.zɑZ&S}غQ޺"KލA^k~+,䌊:ZvWQ޾/>>[eC :uDޔjaWpwD)q$Ly.+tlQglf&u^?RT`Q+<\b88A d8ծiw;$hEaIg2ɀ|R8SPci.Q.2MjY_NU ռh0҆RRocPQckzNSmwʄ('Uj\{nna)zQrnEVM1zy88j)Xtͯ&N5b凇Exy\V@k.gZ2D:`z3^R)aGܥ)]Uf}6'Az(d'6dZ6B꒍Jzu46}>$L+ú V;"雍Ϙ'#XY'\iR4tYUUW w|' ؒ^fάZVUނIJ NrZWSG$+gp 'zUΓDX(!-.rj9 iPfk jد8d"|(_fW!1ɒ^c:[>bxyQMHIZtfTD/2 hw&_G% ?ЃEkBU-1E/p˧T|nx"Mnq+pTvlfIy%dN+sC'Xh<34new+%^Cͪh0H@,&Mc $9(ғR/{Z`'%VTrc\~pUQ7oEEIN0H۔ I5ȅZ:hE!U0XKH)L1/ir#DRWZՅFr%%%F'NghJ2ػuORqYVlu#=fr& ={}\M;>b_l\{>KA{wMuׯIXRWb^H?Kb!i'd\[{c_Żc(M6=J=FxܕEievhT(iF_Ƅ$_ԹO_WGh* 3"L, ֓CV$V鈜rX<܂e^ULMuF?Iq yc/Z95U}f[Y_&RB; i%vyҍHWCyv}:,^-"7Ρ'ڬ4 S5س`.0HP_5RB+ ZIZw%G:1i瞝? .Xw'5].+-%VGREΪOu)ؾNx]G5n?~Ӓpe*?ʩM3!o[;#9Bj}EMXS_ ;׼i4mn~YͱT~rf`Jpg WP_\]U.Z+kTw$ҺxIM`%قgԅ[ -p{w˯f['*.vuY#SJCLq`0U?lf;y {j tP>%M{ d ZMv59.zOO 'lڒ+s4ixJCuР?qU fBs̟ܘ/3UV`UVnlU[=L$3kt$;xȧ!Ce 8dnuh~"s(AK괶?>58(暻wAֿN^^R>t`e0zDH K6J{/pdYgԙ4GvH쎧7[5vd4l(MLpFg('Ӓ4-7S[.ZeXKvf.#TK9wr[W0l -(=Ar!N$[֓mJ|,U?oWK‘O-d)ZMk ەuHݘB4tqYb~޲ƖA@i=FIr-V "[NG_"<+"IyA'>sXLnNU4#;$AڽzEoF].8Cᔓ0''Ɏ.-ZC'!D&8͐ޞCA//pi|)Ӄ3qz!-_ Ҏ7M(Hd -qD a] ࢅ" .W+i;]Iv;:tH \C{?[T%LmghŏRn& R4᱓U 3•mu98u˘ʉ7I#5* xjVtحnV2Zˆ=K8Cֿxq]>z[\^j|w?'k7n4b XYap{vG2=h5Ei(d:^jofQHH!NyXk(٢^mh6 #\`& 9Sazio [M:YjK|왹t.b^OkG΂0Z߰n5yu[&)"Ѕ~wt׃hO " F䮏 8ahtI<-?b[pFW}pi>nD9͸vtH c5WrrvXZSJʡ0g;iY?Uf,!ՙ6gMf'ݽky,ETtHĥIwSwVuRI"t5aű#1BqUw*SE1uLyݱb8s `n1L4" *R1ed PyjBjy*My$@~C)Wak%gd̕y .k•nwy_&YXv.^/ qCM?JܹnsP,[|`.K\tVٛm iäXpܖ +ܗDúGyPS!q{%q鄤@˔2 q  dEV&sy)n(4,4keDOW,Ty4,Wpb~z>X1-à5 U3 "JXGZPGHrA_eCF&pUOn'RǎSu.>|au E(R) sDҋ~Q&!<6` ix g2? sʳL'g>&o8Mj%l,1WH,ako:G/DN $2OtJ@"ѼXZΪƉ^jU+n(?A$@P@qzz ?!R: h38KAy.$?%Ho۴䫻)P,5±\jQ)vvp)r}IuEsԣ7NmB*N lqBUoߢ]4!u3ǪƽIVd6:u51>6iTp#f5! M''vJs7%;rÎp%4iffkЃ@%n1<Ó$Σ Nޏ$ {nO]'~$74( ݶE9rSnZώ78ZPGNdA w!'|8xPt:ml>RE;ºyj͎p>{G܋6ڲst-^Zo0wLŢ&Y_B\Ƅ="R~]{lvH< MV.xY|W-u A գGzA:^$n^y42,)'V4r_$'~O{E3DHޞGfOJJb vW`+u;: v ^>['s(99IE]$&+r>/VɕwqwaclVq2ܫ~aἺ7Q1Պ~vy1~[S_Th:p.|eh\#Ñ6kŤ;[Rab圤r 3en@g76TsΣ&`T1Iĺ؉vH|#P3"|mYp4|{ey恸>)#H'|#INu{]m7̎z7W?FKRBME3VX_J >=df˵g{ӄ$۝ݽ9UjSxhGk#ЂO:J24:Y!I[$MzIzjA7b?UxBFB)+Pa[|X:ތsSSw} [ʔ>zMu-)̆UHaUixQz dSWuQcZ6ghHE'C5?" DnUf}$XY94` \o2}>]"#8QJz7>z>t7\_j%0k02ai+IjLӛHgZ!aʬ[SjhY[gt %>`W;8%q]̼I%HAγZ[EP'7Zg,ud&TP "ny7Ǥؐ4qHd I@٩Tz7y0 c}C)B7sVDj즧zrume̺Aj`b&ΤdiEuJ=B~Kd 6hdؑf8f:J= 캆iؓpעrv̀J/ ə)Fj ٓ}kU&B, HMYmPE6ఢj%ŵ>|!U}R1T=iKG=Y+뇠R@#h9KA*5fGrWdl:f>M )'؉)59h8 䝐#x)-N5?+Mks5l[_ET@30] gOyyq5hc`#h]9̓e5Imft7S1 )EEʤvZ) VMn4&aCx:bxߐh" m"hhJQA,\G'4igXmٽū=bO9I2nk]{'~ˣFI/kjɱxM^I?DS9i=OSbEvpEz[{Fi~7 "+\ݝ>I e#݂v; Pc/v%o]uJ-HcEb:'FT|(j<= F R^jF =4'd#I2bzLܸ))#z( -biF85=l}R !]CRuM I? `u10߄l4@/p:~wULd RߺOĤ˿Jb n2ieLߧuPARxg |BNӓC"B9UЇ٢h_d_sel|Ub̻X=HBEd/R&K'3G<^Ub3-w?{빰c.~مEq3Xf3s.5Q֜JfquQIp̀1XgW.=&hq=j4H6NCuZ]SM}L?I }qsR'}3E걏jH3dudmF\uzHXQ֏ ꆨ.pCώym.Ÿo'ideZxvU2%WUi}Ҝq5 HW%WG@K,TSY#a$R㴨ۍ%5V{H>ޕDz&T[VX/VBY62R]$§QfC#* } 9tSm&rn<C^oˊgLj?q?Vx'$8='$s7&QٰLƓ LdQoUzNÐ p8^ֱC >n襷G ?vdhwEQjf]&l N$W8޺7pL"+fl5ԤF+@<v5Ч -|>d6Yy%nX2 J"`Ou2 y1,0G3r+X7lrF0'rx0^a!N*Ćx@YsP h[7\6ڠѲ8cna*a׎.8+>OoU9$LbvesFw_VQ/ ۇ5]Oh=#G Xǣ{2j0n,=#D*Ot2֓|VS.^m쌽Bo@g&k2a ~ʠշ%.oAuHMy8BLv7u`a[5ԏI SXtסe%tVn,4BWRN/-91\ǷSVS9;BYZRk1M$5e5HS/X%S5l~_GkXI r1 r> . شbpП;;@{im9z:PW-=k)H1D*'a%b y! UTJ%m$ {遬H_m*yo$C9#5J#QK'`6)'}f΂:VAR * l=־ğm,͚AڥRX:U  ivmU7+spTW)j:jT}ԙnӜ)p vUv*>}$;;:yVx<;4EۓY,*.(|@ QN8T1l y-NTQj'éiKg(*;E'̧Dj-8.Wg;?mz >`Kj*GјsLM=隤st!s,g EJ ~GzYGXStXp[ Enp0fwYm2*[}nA?chI l6%p-#J :?Vj(^ׅd٣isH/➵88};8u1 Ɇ o'.eTnQh,l :HS/ZB%ŝ7wP`/?1hOoږl<\ۍz  h{0lT~ }s"3Σr8DAS4ƞ)/M|p(=jҞԴ9BqOƴ5 'JZP:Ñjuz{4Z |i _*z\Ѳ> fn\v }$ uQ=oIxle %|\SV*"Gd: ?PلDkƄzr 0#}8qh N p ~̑M,|5e2\)EsyI GP 5 ǖ'+taVXj[[g~=u&j;.F jHg2n96+ِBc8HfVƐirVœz;@.V4 ;t*y׋sqh(m1p}0j!kҖs=s>||;N:,5 %`/F/΅ES~@2" Ř?"NA?,AD2J`\\:d+!;IH݅i}j3= ݸ eͼ҉ldvv!ȏ!S^T`rׄL1WxΟ9f$fYi=fmԼiuI>S ?J)~{`BHSqxl9 ⧍>:ƣ3[vo=Sߧ]ڵmӈJ),UGQ*n+h`J>"ēZfg0{p]+I47h5ΆSCuqc},OQ %J:Vi4\`fAãlIHoe>s٪Ui su#Ӥ!j[E$X VJVE=g@FgFoXx Ʒϋsy$8: tA_6b{Z]YND]aB=`XFYsIE`N_e!Z?Z:T.u5af]{I:1I8VK}o`Q''(SiZ?.(^&( eRi֐uU„ejiV%:7z!EX^]Ps*>h^ñ CrNt[wI ѧ=azШ6$sYdlTJUAFիWu2rD6N VF+MZ PZTemti&,>sw$>CHIDjFw Iz߭t Hz7sҴdR9<6iC>ZnqPVmN!Vl Ge~ 6*4t+Pه-o@m{pRp0wU*R3Y M/)Uh:c>+.kk bz-|ŅM{ 鬭V WgFX՜sx51۹,2h2ZѻRcq } ▆V;&Kq+lv2V)w^E&w%kI4O-4fG|R, n2%#0ǫB-<'T]I.hB]NK8B_{PsC]HlOe _IHUM~Z^D, t?{k&M8p[\u'Dl( i i^π갭%i][EI鵵PyhZ~Yt!j"{I>J5h;$ zͯŰQIeD*Zv,hyz/k.lV??:4Y{{wɂdP/~yA<- 7dul)aVKJiw/2i`} Ր􊷳EZLOx 6 3Z< Dy("j)ձ9;v' aQʽBҌG by_ $iChs"2e C# m؆X_9C`\5pY"~6ê8 8])IU,{ߧlGi}ߗwCtk}|^DVV} TY{ISr7Vk-@((ڭ~}VFvQjM-ռg$c--+Is5Us:QG%3S戶p)ocRh"3R6JL*h5JS;Nj['=4 P`Η _-q( ?Fi>?+w?hA$I:ПOoKOֹ{kaƭ}9eGe`{|9aKZcS}3RqkA٪e%9^|8Nsd/! B,RM WwX]fۤ񩞾)5aM_+O>(bYYs,5 AK @y cM_hͷp7|(4Sp<ߊ9L膳48pn2C$Y>HͿ#!{'bA9A;a筁ءt1b?&FPMJ{[6ƆdH!gKɓUA $&)*I%PWI>~"-`dy|NJxꇕf9fa(D"! N]<ӆ~v`MK(}u]=F1Wh0.^Ekkc6zR2rm# T <ՅU] %yQ:y**LUQ!5UHDm诞,k0YOh+W=\LP@B02JN<[WiD5xxJ 'AFuMVWjy!2w@$mBhtٗ2郎'X4#jY-܃bQ(b.r4[zH_*U+TyʉuH~9V1 rRG"zͮzou> 02`ƹZviKɨXlc Cv|l7.@GK\ed1m*9s42Ic҆93UZokxFJuC{;T=RM[J(QUX5bjbOW֣'F">8ػBӳB!=u`MOsqy5widnlz#]]'"{8<5>~6n4{6a<*Cf©$Trp|င |&cdo<ѽddCb_x9TW?"sLkģ^#Dp2Tso"|k jh &gnN[ъ5e^5}iP7\^D)I&-ڣy4 묬˜I!p|(v$2~d"{R Лx]A]fd樶|i6o0GNi vMQ΁7Fy t qG=Uu?Ü>a֊J/2Yu ΅4Xtc 2qgC lPd14<ӲP T jRGʆ`,s6<-+a3 ˫?'Ȁ@k~&<^wU٦"5noSyb$?:Q=FUQzW[M:qhRg$?%g(W_9Hֲ!P #e /*zkC`GnqaH&<`kWMưه9w{5^_FLc T0XJ-"-AdSw.3I"6#^PplzSznc>*.w|v>9Zm܉8VA@nk'$dos/Nly Gou{f9ߠؙD5f9TX{FC-Qj/HAS05L{fHsEo8c~j [os>@Y#\+$?W]7gI޻s b~)$vHZ&77*r뚅puڀ5v'PQnjAsZ>錵 $ WSTV1,V+38RVLx3\2g}Z$Ti ngQo@3C?PDqWd jhTige³Q[45ia @T>2YqBJFOlg!!328=U\9%#p< s-@NnHo\ ְl^ݤŧ4:KQh1e`w6vaKzSMҡVKuzC7RI`DkOC3Nܺ.D({2;L$bcRh>Q<{qu ͘rϞ0}_̶PFOy\oR^m!)91r&?+K" Qw *HpE B^R y{S bC(O{t;&Nb7\;>VK]hIv|ѠQVVV{ƾ|[k1 j::@"=d|[1^5Ia3]jb5^< ͂NUCO4t IKL`8SBS%9[gj)wjFogY#o6 ^/O$e黲䯸90qؓM>NWW4 Y@ VmP{R|7٧xee}$QRork`h[e#d ^,K+ _^TbC?oh9_#vA+N4TӮÁmKJPt2Nv^s_7mQIߤ=3UݩjE 42ǵȉCMMUC>wIkUL8AQAbݢ5?&WYR{QFgji(5qv` NuZK/'T-]e>j׾3&LSQ6-OY;!=:d+ 56n&W,Pau,T 5/X(d|%$ʤd--xZ'V{ !Aj^&b:O/RnvyfrKr+|兓hp::rc.e}WPhdO}9꿿2>˩1.t.o4^Q?'p0قfGM8keq9{ui煦ewH W:#}H1J.ݷq*}1::SڙG|aq}%^rl-dF{cIh9!󧊯?m07*Ʈl.팤zH]fYS d>(fQHPJgw4ͳN %[@Bg sS{KCmlGߝ7.=|m9s=`|&$i~{?|2c躄4{"σuB%DO5 xV+(h综hk@SP,e˱L&TL&V7;dX|@-+׳Ng愖ykGH*s!R]zJ) *肢ej{}uN/(\\+)F.Ux6pw_𺓥&,iʷ idQi]6 $FO>y&:{Ζl.S.Pm6] jW*Rjr]EQNK]rV8Qc *]h[XkOUzjaZЬP:ŷc v"_'ݯ?Y[ƎSH eK djpMGd8I ^d N\UFDG%x$00z{a3kυ^C 8V&"/ 2BكHG U$aVsu6s ]$JU2xELVKO$qԑŹӏ10P[{i2҄ U@Qp pqlݢ 9IzW*@6YKWA s-v :AHo&j \pI58d%\SY7q7ma(-,f':WpzrW'YkV X8T#eُT˲Śz}MBxOd}"IV2Jk,I$s唊B!+n+|P(|4NjCZa^-0!;49߇j5tKT˜fvJp64nWd=Yҕ }6 :$NWWY~"s")ׄnM6lPHK -D׫LpEEosGm>.Zc~< Y/=[orY'r jΪkCgVʹ1CD0G׍51Y%(]xkMMxX o&5ulT;LxܗT ~>p =Ձת1oejzXUX?80R]k$ zĊmTاUifu!}{-J 1(  [R&l+ u" 4e?hj~Ȥƍ.`&\9QUi[M "c= w`:y(|E&uE+[@pFlOY}lPb(LΫp:3Dl;nXT)ۣg: R)@ qej`S|RF@cqX5ezm0ԚN=5vB *A[ZްUlCvjZhίJz6{05P&ɜmm :S_륱fL-T{ODmFY\tJPK9ת6~(/*,Km93Ө 0,#3MW ӺO0_I lEΞHr+%zh4MFʯw?W]VSljc)3Pwi 2PBRxەX$٣ޢ1ϒPFEt|'juK]]B  m\gV Ajݮ LðHhkϻmY'?I׆4 Ei-{Ytn+t^3ӐhE #| 覮`ШhkŌuK?q{oS(xyTxH< B 6fHoOm^_ye}}- O@' G[s`'؀r ә p:5PZ4=R0ɢg"Ӏ MU6̩fwȴQssXO5̨)Sq[5Inj\YfQQ3R_TGmkr>+Q FL.v;;&9$.3|Om{{eGYKënZY'#n=ycѲ<`Bo(-(eFؗOd:еu]_fd<,SF'u5} c$\d0q5|RYzA@ 'P}BfE_4&Hu-9Hi^i)%F8:\JV\AN&e2dI|5*y:~n=ӳ=1"gV`Gz_\A*1KINS;Eړ.?]Z(Yk|lp&3*zdre⚰mYG >vLzz 'W3ӎ$> G2H_ RT =LGPx6;}:ǪQ%@bxIG  ZLƋʈ~XT6@9gC]b]t3YU 0pHJ+[Gн>;wUnBQrEh) (eKȖlC.;&l+jo$!+<5rs7$iρKr*GXp_3ŷ p6י]~gF&X8& Ԅ?lBZ4RjH왒,Zfd̟ԁJ^Cy>2d($yK?MxMHtӆcKL⌏31(L;~)ЃqVȮ^̮s4{f[s>yR≠ϻÉ\#Vt"v!xI ۢYЊSbuE%J] : CkwrbwP۶ gUɡr.j:OG(Hy[y3#PM×z7ŧ #6F4="Ra=ڈ17 .+|Dcl0Z%}&=!FucZ&G$YK `ݛ*XfZ#!W$9;]UN$6'33NXYXe $}{XNvZ"2*x&;  Fz)+HDөCciY$m{!+pi4$0mXAC3}:'wjbNqv*NK;OXb,u|$ ӍnawͣGK>ϞOЎw 6VҔ5MR!Xl7f̐XOm=,QR] I"S $zWn0'Ŭ6 o %-fK eVZL4WJOYru} Sy)f)V S\&. H+dʖ$ VP問qv] 'j)ɷZ>:Ĕz?U J`@|"̊X.|6Nc Pkl ^~)$"qϢ5TJ:C 8 Gh_M+Ճi l)rvֹ)Vv-;iڰfK NlI:&Ʉ~nijI)Dm=OIwaxaJ_u:gp863K \@wj#2 oV3 mŅjJ VM/ͦ_>h]&[o@vi/z[: ?o)qϵvD , H|ZgE*{@qB8(2%;OI_C)"R_j¨v]WD~ HRs<)#nu= Ʊ2X@2fDh~tbd!@f ?hVX%y{x٫]:bC@+("K>c-IQPaQ9`6goцޙCIQ9{4p8Ddų͑B7Pa,IQ>@҈Fm!P\,9tY+`,nZ>|F-j4rǕ{!"dءOʪ-8}8%CS[R(^1Ӡ3tYp=  G:1L e9?C#atYgT^+&>B3^a4ȴE8WZLnk I+XG!q1Cg:yL뭾r G@y peJiK'\nQk4nt6$xB =S[$S]hW8A SG F y&fȷ8ˬe68'܁!fAgJW[`}#aC=Wyg0.+r2OM Dh/ZjOlŪ-X+Onuf׭s'+7mMGn^٠d?y>"|^*MK.AiR61WA`ʪ]:)ڮ֒XUioMdbNGȶBxL-E.rU,{gdDsK*m}3񕱯l~EFF)v%E8_ʸtΥDQFv[mSRBď$JZ$#@~R7''|ioխ_Ś6ԉG}.{b@=83MpS3zvR-60z~it2?9)Hia̰d/1dvW4VJ|dVXJi|U:YQ+tuH}YO v%#,u8p uMvFfYwnF>c˦O1Lѓђx; 3Ekp7b~А9Ǔ` sN.ƍgZ >s`+{[KOӱZ2@74/fvx0Qt,ݷ P}ʰ'mWs7Mɤ%{Dٱ&fJa(+ wOod2vۥrR9 *5r=bm-f=$fIlw<ǫNu 5E>s=ٶb 0p_[jIף gj^lmFGiܝ2!x3R»nKꃄTMIP5fG SNnkj:HS?ᅦȇ};5%xX-Ǟc!Ȏ*irZώ m4Hu}r@ ? =R bE֣n쩍2.|H.H˼-%W.1"pSMȋjד[?Kh'w5V]]V2t|Ia_~޾ WH[wrլL W.X[6xo@|o%D[@&Å %[4DzV%>ϟe~3TT>'=^cOg!muWy>GKH5j=)M)f߳8c]1Z>kFn͆ȜMף_Wɰ2gq)vE]7Fd4;I$G.]EMǷ5!KCNzxB ( o|'L?^)iUIo6tAhM*z[zrI;)O xE"=umP%-k.vVoɂ 5Wתc]@&9 UxtapvH͋n:ߗOd{>+`@&P0d[6c/}@v~f^GCj<~GRPڰdRylvZO{LJ!Wr@$hWΐ\ZdWA(A| 髖I JŎC)^ 겟I-5&bof/ _<ٿ)0<*c,:q}ubP|>ԁ#{Ǫyl$&up6Gg`oQa.MElHRjCf_'sULyJ\@e$v`b+hfLקSǘܠn(& nӮ3 SEQ|V_/4 "ÈT:9ѵE8K(;BQưvGx|đxTmу)҈Q$5+ ²4!0,ܪ XVy!' 19s9;O4=~ƐXqr!Y^;8͜A9cm>dU /JMsiɏQMvr;E_O }Õ$la_8.I>MeVfKᢟ L%ԙTr Mv]CoM!CM.q?zYN)㐹3LLgIN}zW.&P>pvwǪBp3EvhU?R$:o [XfI2kI?bL i&q>]JFg< MQ[X@ 9~lrAoۢ"rgI$F5/rSʓ=VA "t=A0Z[cށf,, V .Fj6Zcλ:]w-w?Nnr n9O81H}56 4H|%x"Tb7{vvW]\N8 rM깏EӘLRs@p6<+IV-oC׋jX%"#wӀz"F^J3%bqWBo l[HcFEq=IZ~~ aʾ~MP@ ;wVGŒT!)Orl^_VD\-SIY {^[ 6|վ.P^ ^7JPkWE@='\&C6K(aʫSG~dUhm{ԑ5&YM35o;Uc2: d2HUT&CUו 'HP{aKbs2hmKKk Uo(~;H{ҫ((㗁C?YbKA8?/T0jk8}\ obRFeZ"H/䳤‘=l3) yk0֓xO9Ľ%'I7G(' ^bѥWqb)i~/ 61S clJO\3Qty~*ezb:xDqn@{U+^U}p3 ((v͔4Y\o$#$!hH**@A/Vu,.mN%*#I$t>q!e򸄈1Wus~<+:^nz`":i7xZkG ܯA2+@n||²W\QGgڍe N۳mk6N\6ꍕku^{rI((_s/oNojo4h/}s'A?:?}ƆD']tZoo҉PKڵIuW+46z$[o$F3GW߲+N_+1;wo*tedd#6n d"Oz3vFS'̈oI;"$e8: `6|/|iJSR~啋%!2_*r7(f oӈ-QeC}o>هbkX^gfPdK}Q滥 y>_+Q;г:M*t4jǒ2sx7ᓗ|ƕ}hX#G;V"hח]k{֑tϾO&<}VNLhH*x,97,F7s/AgZaJs~ԇ8H싞bG\t=megbRn΢h~HsxWi:}5g[M٥>7ՆQT/N *3BJ?}b`LHlpVo$IX?}C)6K"`t#Lta ,?ݽvRI?}?d@fC$a}ԧVs)xw2xH^tCڐٷƈ1^4M:zL^)sŦp=! 9(i2}'" 32IpлY`yQށ VWiJei#Gc;k)G$A C : EQ61H'9#{tQ*%d~q,X$[V2 wZPdɊMw 7\缪JbtUq e?e5L`+m\T*]Xϕ(ªRɛT0B2LE>\kzz+XM߈+ȋN||ҠDuKbcy%ߤTLWF=]ɷyMt\KWzFSU}ŋ*wz )~A1^Mh Ƶ KJ_9ѷڼT^l4ٲPPZ>>jK(;26G ~Gapa~06%oe%}Jftg"k4Z[1QK F_( )kj҇y5x