~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm64/kvm/hypercalls.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/arm64/kvm/hypercalls.c (Version linux-6.12-rc7) and /arch/sparc/kvm/hypercalls.c (Version linux-4.16.18)


  1 // SPDX-License-Identifier: GPL-2.0                 1 
  2 // Copyright (C) 2019 Arm Ltd.                    
  3                                                   
  4 #include <linux/arm-smccc.h>                      
  5 #include <linux/kvm_host.h>                       
  6                                                   
  7 #include <asm/kvm_emulate.h>                      
  8                                                   
  9 #include <kvm/arm_hypercalls.h>                   
 10 #include <kvm/arm_psci.h>                         
 11                                                   
 12 #define KVM_ARM_SMCCC_STD_FEATURES                
 13         GENMASK(KVM_REG_ARM_STD_BMAP_BIT_COUNT    
 14 #define KVM_ARM_SMCCC_STD_HYP_FEATURES            
 15         GENMASK(KVM_REG_ARM_STD_HYP_BMAP_BIT_C    
 16 #define KVM_ARM_SMCCC_VENDOR_HYP_FEATURES         
 17         GENMASK(KVM_REG_ARM_VENDOR_HYP_BMAP_BI    
 18                                                   
 19 static void kvm_ptp_get_time(struct kvm_vcpu *    
 20 {                                                 
 21         struct system_time_snapshot systime_sn    
 22         u64 cycles = ~0UL;                        
 23         u32 feature;                              
 24                                                   
 25         /*                                        
 26          * system time and counter value must     
 27          * time to keep consistency and precis    
 28          */                                       
 29         ktime_get_snapshot(&systime_snapshot);    
 30                                                   
 31         /*                                        
 32          * This is only valid if the current c    
 33          * architected counter, as this is the    
 34          * can see.                               
 35          */                                       
 36         if (systime_snapshot.cs_id != CSID_ARM    
 37                 return;                           
 38                                                   
 39         /*                                        
 40          * The guest selects one of the two re    
 41          * (virtual or physical) with the firs    
 42          * call. In case the identifier is not    
 43          */                                       
 44         feature = smccc_get_arg1(vcpu);           
 45         switch (feature) {                        
 46         case KVM_PTP_VIRT_COUNTER:                
 47                 cycles = systime_snapshot.cycl    
 48                 break;                            
 49         case KVM_PTP_PHYS_COUNTER:                
 50                 cycles = systime_snapshot.cycl    
 51                 break;                            
 52         default:                                  
 53                 return;                           
 54         }                                         
 55                                                   
 56         /*                                        
 57          * This relies on the top bit of val[0    
 58          * valid values of system time, becaus    
 59          * in the future (about 292 years from    
 60          * nobody will give a damn about it).     
 61          */                                       
 62         val[0] = upper_32_bits(systime_snapsho    
 63         val[1] = lower_32_bits(systime_snapsho    
 64         val[2] = upper_32_bits(cycles);           
 65         val[3] = lower_32_bits(cycles);           
 66 }                                                 
 67                                                   
 68 static bool kvm_smccc_default_allowed(u32 func    
 69 {                                                 
 70         switch (func_id) {                        
 71         /*                                        
 72          * List of function-ids that are not g    
 73          * feature firmware registers, and are    
 74          * servicing the call by default.         
 75          */                                       
 76         case ARM_SMCCC_VERSION_FUNC_ID:           
 77         case ARM_SMCCC_ARCH_FEATURES_FUNC_ID:     
 78                 return true;                      
 79         default:                                  
 80                 /* PSCI 0.2 and up is in the 0    
 81                 if (ARM_SMCCC_OWNER_NUM(func_i    
 82                     ARM_SMCCC_FUNC_NUM(func_id    
 83                         return true;              
 84                                                   
 85                 /*                                
 86                  * KVM's PSCI 0.1 doesn't comp    
 87                  * its own function-id base an    
 88                  */                               
 89                 if (func_id >= KVM_PSCI_FN(0)     
 90                         return true;              
 91                                                   
 92                 return false;                     
 93         }                                         
 94 }                                                 
 95                                                   
 96 static bool kvm_smccc_test_fw_bmap(struct kvm_    
 97 {                                                 
 98         struct kvm_smccc_features *smccc_feat     
 99                                                   
100         switch (func_id) {                        
101         case ARM_SMCCC_TRNG_VERSION:              
102         case ARM_SMCCC_TRNG_FEATURES:             
103         case ARM_SMCCC_TRNG_GET_UUID:             
104         case ARM_SMCCC_TRNG_RND32:                
105         case ARM_SMCCC_TRNG_RND64:                
106                 return test_bit(KVM_REG_ARM_ST    
107                                 &smccc_feat->s    
108         case ARM_SMCCC_HV_PV_TIME_FEATURES:       
109         case ARM_SMCCC_HV_PV_TIME_ST:             
110                 return test_bit(KVM_REG_ARM_ST    
111                                 &smccc_feat->s    
112         case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES    
113         case ARM_SMCCC_VENDOR_HYP_CALL_UID_FUN    
114                 return test_bit(KVM_REG_ARM_VE    
115                                 &smccc_feat->v    
116         case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC    
117                 return test_bit(KVM_REG_ARM_VE    
118                                 &smccc_feat->v    
119         default:                                  
120                 return false;                     
121         }                                         
122 }                                                 
123                                                   
124 #define SMC32_ARCH_RANGE_BEGIN  ARM_SMCCC_VERS    
125 #define SMC32_ARCH_RANGE_END    ARM_SMCCC_CALL    
126                                                   
127                                                   
128                                                   
129 #define SMC64_ARCH_RANGE_BEGIN  ARM_SMCCC_CALL    
130                                                   
131                                                   
132 #define SMC64_ARCH_RANGE_END    ARM_SMCCC_CALL    
133                                                   
134                                                   
135                                                   
136 static int kvm_smccc_filter_insert_reserved(st    
137 {                                                 
138         int r;                                    
139                                                   
140         /*                                        
141          * Prevent userspace from handling any    
142          * range, avoiding the risk of misrepr    
143          * to the guest.                          
144          */                                       
145         r = mtree_insert_range(&kvm->arch.smcc    
146                                SMC32_ARCH_RANG    
147                                xa_mk_value(KVM    
148                                GFP_KERNEL_ACCO    
149         if (r)                                    
150                 goto out_destroy;                 
151                                                   
152         r = mtree_insert_range(&kvm->arch.smcc    
153                                SMC64_ARCH_RANG    
154                                xa_mk_value(KVM    
155                                GFP_KERNEL_ACCO    
156         if (r)                                    
157                 goto out_destroy;                 
158                                                   
159         return 0;                                 
160 out_destroy:                                      
161         mtree_destroy(&kvm->arch.smccc_filter)    
162         return r;                                 
163 }                                                 
164                                                   
165 static bool kvm_smccc_filter_configured(struct    
166 {                                                 
167         return !mtree_empty(&kvm->arch.smccc_f    
168 }                                                 
169                                                   
170 static int kvm_smccc_set_filter(struct kvm *kv    
171 {                                                 
172         const void *zero_page = page_to_virt(Z    
173         struct kvm_smccc_filter filter;           
174         u32 start, end;                           
175         int r;                                    
176                                                   
177         if (copy_from_user(&filter, uaddr, siz    
178                 return -EFAULT;                   
179                                                   
180         if (memcmp(filter.pad, zero_page, size    
181                 return -EINVAL;                   
182                                                   
183         start = filter.base;                      
184         end = start + filter.nr_functions - 1;    
185                                                   
186         if (end < start || filter.action >= NR    
187                 return -EINVAL;                   
188                                                   
189         mutex_lock(&kvm->arch.config_lock);       
190                                                   
191         if (kvm_vm_has_ran_once(kvm)) {           
192                 r = -EBUSY;                       
193                 goto out_unlock;                  
194         }                                         
195                                                   
196         if (!kvm_smccc_filter_configured(kvm))    
197                 r = kvm_smccc_filter_insert_re    
198                 if (WARN_ON_ONCE(r))              
199                         goto out_unlock;          
200         }                                         
201                                                   
202         r = mtree_insert_range(&kvm->arch.smcc    
203                                xa_mk_value(fil    
204 out_unlock:                                       
205         mutex_unlock(&kvm->arch.config_lock);     
206         return r;                                 
207 }                                                 
208                                                   
209 static u8 kvm_smccc_filter_get_action(struct k    
210 {                                                 
211         unsigned long idx = func_id;              
212         void *val;                                
213                                                   
214         if (!kvm_smccc_filter_configured(kvm))    
215                 return KVM_SMCCC_FILTER_HANDLE    
216                                                   
217         /*                                        
218          * But where's the error handling, you    
219          *                                        
220          * mt_find() returns NULL if no entry     
221          * to match KVM_SMCCC_FILTER_HANDLE.      
222          */                                       
223         val = mt_find(&kvm->arch.smccc_filter,    
224         return xa_to_value(val);                  
225 }                                                 
226                                                   
227 static u8 kvm_smccc_get_action(struct kvm_vcpu    
228 {                                                 
229         /*                                        
230          * Intervening actions in the SMCCC fi    
231          * pseudo-firmware register bitmaps.      
232          */                                       
233         u8 action = kvm_smccc_filter_get_actio    
234         if (action != KVM_SMCCC_FILTER_HANDLE)    
235                 return action;                    
236                                                   
237         if (kvm_smccc_test_fw_bmap(vcpu, func_    
238             kvm_smccc_default_allowed(func_id)    
239                 return KVM_SMCCC_FILTER_HANDLE    
240                                                   
241         return KVM_SMCCC_FILTER_DENY;             
242 }                                                 
243                                                   
244 static void kvm_prepare_hypercall_exit(struct     
245 {                                                 
246         u8 ec = ESR_ELx_EC(kvm_vcpu_get_esr(vc    
247         struct kvm_run *run = vcpu->run;          
248         u64 flags = 0;                            
249                                                   
250         if (ec == ESR_ELx_EC_SMC32 || ec == ES    
251                 flags |= KVM_HYPERCALL_EXIT_SM    
252                                                   
253         if (!kvm_vcpu_trap_il_is32bit(vcpu))      
254                 flags |= KVM_HYPERCALL_EXIT_16    
255                                                   
256         run->exit_reason = KVM_EXIT_HYPERCALL;    
257         run->hypercall = (typeof(run->hypercal    
258                 .nr     = func_id,                
259                 .flags  = flags,                  
260         };                                        
261 }                                                 
262                                                   
263 int kvm_smccc_call_handler(struct kvm_vcpu *vc    
264 {                                                 
265         struct kvm_smccc_features *smccc_feat     
266         u32 func_id = smccc_get_function(vcpu)    
267         u64 val[4] = {SMCCC_RET_NOT_SUPPORTED}    
268         u32 feature;                              
269         u8 action;                                
270         gpa_t gpa;                                
271                                                   
272         action = kvm_smccc_get_action(vcpu, fu    
273         switch (action) {                         
274         case KVM_SMCCC_FILTER_HANDLE:             
275                 break;                            
276         case KVM_SMCCC_FILTER_DENY:               
277                 goto out;                         
278         case KVM_SMCCC_FILTER_FWD_TO_USER:        
279                 kvm_prepare_hypercall_exit(vcp    
280                 return 0;                         
281         default:                                  
282                 WARN_RATELIMIT(1, "Unhandled S    
283                 goto out;                         
284         }                                         
285                                                   
286         switch (func_id) {                        
287         case ARM_SMCCC_VERSION_FUNC_ID:           
288                 val[0] = ARM_SMCCC_VERSION_1_1    
289                 break;                            
290         case ARM_SMCCC_ARCH_FEATURES_FUNC_ID:     
291                 feature = smccc_get_arg1(vcpu)    
292                 switch (feature) {                
293                 case ARM_SMCCC_ARCH_WORKAROUND    
294                         switch (arm64_get_spec    
295                         case SPECTRE_VULNERABL    
296                                 break;            
297                         case SPECTRE_MITIGATED    
298                                 val[0] = SMCCC    
299                                 break;            
300                         case SPECTRE_UNAFFECTE    
301                                 val[0] = SMCCC    
302                                 break;            
303                         }                         
304                         break;                    
305                 case ARM_SMCCC_ARCH_WORKAROUND    
306                         switch (arm64_get_spec    
307                         case SPECTRE_VULNERABL    
308                                 break;            
309                         case SPECTRE_MITIGATED    
310                                 /*                
311                                  * SSBS everyw    
312                                  * support, as    
313                                  * indicated t    
314                                  * safe.          
315                                  *                
316                                  * Otherwise,     
317                                  * to the gues    
318                                  * guest stays    
319                                  */               
320                                 if (kvm_has_fe    
321                                         break;    
322                                 fallthrough;      
323                         case SPECTRE_UNAFFECTE    
324                                 val[0] = SMCCC    
325                                 break;            
326                         }                         
327                         break;                    
328                 case ARM_SMCCC_ARCH_WORKAROUND    
329                         switch (arm64_get_spec    
330                         case SPECTRE_VULNERABL    
331                                 break;            
332                         case SPECTRE_MITIGATED    
333                                 val[0] = SMCCC    
334                                 break;            
335                         case SPECTRE_UNAFFECTE    
336                                 val[0] = SMCCC    
337                                 break;            
338                         }                         
339                         break;                    
340                 case ARM_SMCCC_HV_PV_TIME_FEAT    
341                         if (test_bit(KVM_REG_A    
342                                      &smccc_fe    
343                                 val[0] = SMCCC    
344                         break;                    
345                 }                                 
346                 break;                            
347         case ARM_SMCCC_HV_PV_TIME_FEATURES:       
348                 val[0] = kvm_hypercall_pv_feat    
349                 break;                            
350         case ARM_SMCCC_HV_PV_TIME_ST:             
351                 gpa = kvm_init_stolen_time(vcp    
352                 if (gpa != INVALID_GPA)           
353                         val[0] = gpa;             
354                 break;                            
355         case ARM_SMCCC_VENDOR_HYP_CALL_UID_FUN    
356                 val[0] = ARM_SMCCC_VENDOR_HYP_    
357                 val[1] = ARM_SMCCC_VENDOR_HYP_    
358                 val[2] = ARM_SMCCC_VENDOR_HYP_    
359                 val[3] = ARM_SMCCC_VENDOR_HYP_    
360                 break;                            
361         case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES    
362                 val[0] = smccc_feat->vendor_hy    
363                 break;                            
364         case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC    
365                 kvm_ptp_get_time(vcpu, val);      
366                 break;                            
367         case ARM_SMCCC_TRNG_VERSION:              
368         case ARM_SMCCC_TRNG_FEATURES:             
369         case ARM_SMCCC_TRNG_GET_UUID:             
370         case ARM_SMCCC_TRNG_RND32:                
371         case ARM_SMCCC_TRNG_RND64:                
372                 return kvm_trng_call(vcpu);       
373         default:                                  
374                 return kvm_psci_call(vcpu);       
375         }                                         
376                                                   
377 out:                                              
378         smccc_set_retval(vcpu, val[0], val[1],    
379         return 1;                                 
380 }                                                 
381                                                   
382 static const u64 kvm_arm_fw_reg_ids[] = {         
383         KVM_REG_ARM_PSCI_VERSION,                 
384         KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1,      
385         KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2,      
386         KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3,      
387         KVM_REG_ARM_STD_BMAP,                     
388         KVM_REG_ARM_STD_HYP_BMAP,                 
389         KVM_REG_ARM_VENDOR_HYP_BMAP,              
390 };                                                
391                                                   
392 void kvm_arm_init_hypercalls(struct kvm *kvm)     
393 {                                                 
394         struct kvm_smccc_features *smccc_feat     
395                                                   
396         smccc_feat->std_bmap = KVM_ARM_SMCCC_S    
397         smccc_feat->std_hyp_bmap = KVM_ARM_SMC    
398         smccc_feat->vendor_hyp_bmap = KVM_ARM_    
399                                                   
400         mt_init(&kvm->arch.smccc_filter);         
401 }                                                 
402                                                   
403 void kvm_arm_teardown_hypercalls(struct kvm *k    
404 {                                                 
405         mtree_destroy(&kvm->arch.smccc_filter)    
406 }                                                 
407                                                   
408 int kvm_arm_get_fw_num_regs(struct kvm_vcpu *v    
409 {                                                 
410         return ARRAY_SIZE(kvm_arm_fw_reg_ids);    
411 }                                                 
412                                                   
413 int kvm_arm_copy_fw_reg_indices(struct kvm_vcp    
414 {                                                 
415         int i;                                    
416                                                   
417         for (i = 0; i < ARRAY_SIZE(kvm_arm_fw_    
418                 if (put_user(kvm_arm_fw_reg_id    
419                         return -EFAULT;           
420         }                                         
421                                                   
422         return 0;                                 
423 }                                                 
424                                                   
425 #define KVM_REG_FEATURE_LEVEL_MASK      GENMAS    
426                                                   
427 /*                                                
428  * Convert the workaround level into an easy-t    
429  * values mean better protection.                 
430  */                                               
431 static int get_kernel_wa_level(struct kvm_vcpu    
432 {                                                 
433         switch (regid) {                          
434         case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND    
435                 switch (arm64_get_spectre_v2_s    
436                 case SPECTRE_VULNERABLE:          
437                         return KVM_REG_ARM_SMC    
438                 case SPECTRE_MITIGATED:           
439                         return KVM_REG_ARM_SMC    
440                 case SPECTRE_UNAFFECTED:          
441                         return KVM_REG_ARM_SMC    
442                 }                                 
443                 return KVM_REG_ARM_SMCCC_ARCH_    
444         case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND    
445                 switch (arm64_get_spectre_v4_s    
446                 case SPECTRE_MITIGATED:           
447                         /*                        
448                          * As for the hypercal    
449                          * don't have any FW m    
450                          * all times.             
451                          */                       
452                         if (kvm_has_feat(vcpu-    
453                                 return KVM_REG    
454                         fallthrough;              
455                 case SPECTRE_UNAFFECTED:          
456                         return KVM_REG_ARM_SMC    
457                 case SPECTRE_VULNERABLE:          
458                         return KVM_REG_ARM_SMC    
459                 }                                 
460                 break;                            
461         case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND    
462                 switch (arm64_get_spectre_bhb_    
463                 case SPECTRE_VULNERABLE:          
464                         return KVM_REG_ARM_SMC    
465                 case SPECTRE_MITIGATED:           
466                         return KVM_REG_ARM_SMC    
467                 case SPECTRE_UNAFFECTED:          
468                         return KVM_REG_ARM_SMC    
469                 }                                 
470                 return KVM_REG_ARM_SMCCC_ARCH_    
471         }                                         
472                                                   
473         return -EINVAL;                           
474 }                                                 
475                                                   
476 int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu,     
477 {                                                 
478         struct kvm_smccc_features *smccc_feat     
479         void __user *uaddr = (void __user *)(l    
480         u64 val;                                  
481                                                   
482         switch (reg->id) {                        
483         case KVM_REG_ARM_PSCI_VERSION:            
484                 val = kvm_psci_version(vcpu);     
485                 break;                            
486         case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND    
487         case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND    
488         case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND    
489                 val = get_kernel_wa_level(vcpu    
490                 break;                            
491         case KVM_REG_ARM_STD_BMAP:                
492                 val = READ_ONCE(smccc_feat->st    
493                 break;                            
494         case KVM_REG_ARM_STD_HYP_BMAP:            
495                 val = READ_ONCE(smccc_feat->st    
496                 break;                            
497         case KVM_REG_ARM_VENDOR_HYP_BMAP:         
498                 val = READ_ONCE(smccc_feat->ve    
499                 break;                            
500         default:                                  
501                 return -ENOENT;                   
502         }                                         
503                                                   
504         if (copy_to_user(uaddr, &val, KVM_REG_    
505                 return -EFAULT;                   
506                                                   
507         return 0;                                 
508 }                                                 
509                                                   
510 static int kvm_arm_set_fw_reg_bmap(struct kvm_    
511 {                                                 
512         int ret = 0;                              
513         struct kvm *kvm = vcpu->kvm;              
514         struct kvm_smccc_features *smccc_feat     
515         unsigned long *fw_reg_bmap, fw_reg_fea    
516                                                   
517         switch (reg_id) {                         
518         case KVM_REG_ARM_STD_BMAP:                
519                 fw_reg_bmap = &smccc_feat->std    
520                 fw_reg_features = KVM_ARM_SMCC    
521                 break;                            
522         case KVM_REG_ARM_STD_HYP_BMAP:            
523                 fw_reg_bmap = &smccc_feat->std    
524                 fw_reg_features = KVM_ARM_SMCC    
525                 break;                            
526         case KVM_REG_ARM_VENDOR_HYP_BMAP:         
527                 fw_reg_bmap = &smccc_feat->ven    
528                 fw_reg_features = KVM_ARM_SMCC    
529                 break;                            
530         default:                                  
531                 return -ENOENT;                   
532         }                                         
533                                                   
534         /* Check for unsupported bit */           
535         if (val & ~fw_reg_features)               
536                 return -EINVAL;                   
537                                                   
538         mutex_lock(&kvm->arch.config_lock);       
539                                                   
540         if (kvm_vm_has_ran_once(kvm) && val !=    
541                 ret = -EBUSY;                     
542                 goto out;                         
543         }                                         
544                                                   
545         WRITE_ONCE(*fw_reg_bmap, val);            
546 out:                                              
547         mutex_unlock(&kvm->arch.config_lock);     
548         return ret;                               
549 }                                                 
550                                                   
551 int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu,     
552 {                                                 
553         void __user *uaddr = (void __user *)(l    
554         u64 val;                                  
555         int wa_level;                             
556                                                   
557         if (KVM_REG_SIZE(reg->id) != sizeof(va    
558                 return -ENOENT;                   
559         if (copy_from_user(&val, uaddr, KVM_RE    
560                 return -EFAULT;                   
561                                                   
562         switch (reg->id) {                        
563         case KVM_REG_ARM_PSCI_VERSION:            
564         {                                         
565                 bool wants_02;                    
566                                                   
567                 wants_02 = vcpu_has_feature(vc    
568                                                   
569                 switch (val) {                    
570                 case KVM_ARM_PSCI_0_1:            
571                         if (wants_02)             
572                                 return -EINVAL    
573                         vcpu->kvm->arch.psci_v    
574                         return 0;                 
575                 case KVM_ARM_PSCI_0_2:            
576                 case KVM_ARM_PSCI_1_0:            
577                 case KVM_ARM_PSCI_1_1:            
578                         if (!wants_02)            
579                                 return -EINVAL    
580                         vcpu->kvm->arch.psci_v    
581                         return 0;                 
582                 }                                 
583                 break;                            
584         }                                         
585                                                   
586         case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND    
587         case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND    
588                 if (val & ~KVM_REG_FEATURE_LEV    
589                         return -EINVAL;           
590                                                   
591                 if (get_kernel_wa_level(vcpu,     
592                         return -EINVAL;           
593                                                   
594                 return 0;                         
595                                                   
596         case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND    
597                 if (val & ~(KVM_REG_FEATURE_LE    
598                             KVM_REG_ARM_SMCCC_    
599                         return -EINVAL;           
600                                                   
601                 /* The enabled bit must not be    
602                 if ((val & KVM_REG_ARM_SMCCC_A    
603                     (val & KVM_REG_FEATURE_LEV    
604                         return -EINVAL;           
605                                                   
606                 /*                                
607                  * Map all the possible incomi    
608                  * really want to deal with.      
609                  */                               
610                 switch (val & KVM_REG_FEATURE_    
611                 case KVM_REG_ARM_SMCCC_ARCH_WO    
612                 case KVM_REG_ARM_SMCCC_ARCH_WO    
613                         wa_level = KVM_REG_ARM    
614                         break;                    
615                 case KVM_REG_ARM_SMCCC_ARCH_WO    
616                 case KVM_REG_ARM_SMCCC_ARCH_WO    
617                         wa_level = KVM_REG_ARM    
618                         break;                    
619                 default:                          
620                         return -EINVAL;           
621                 }                                 
622                                                   
623                 /*                                
624                  * We can deal with NOT_AVAIL     
625                  * other way around.              
626                  */                               
627                 if (get_kernel_wa_level(vcpu,     
628                         return -EINVAL;           
629                                                   
630                 return 0;                         
631         case KVM_REG_ARM_STD_BMAP:                
632         case KVM_REG_ARM_STD_HYP_BMAP:            
633         case KVM_REG_ARM_VENDOR_HYP_BMAP:         
634                 return kvm_arm_set_fw_reg_bmap    
635         default:                                  
636                 return -ENOENT;                   
637         }                                         
638                                                   
639         return -EINVAL;                           
640 }                                                 
641                                                   
642 int kvm_vm_smccc_has_attr(struct kvm *kvm, str    
643 {                                                 
644         switch (attr->attr) {                     
645         case KVM_ARM_VM_SMCCC_FILTER:             
646                 return 0;                         
647         default:                                  
648                 return -ENXIO;                    
649         }                                         
650 }                                                 
651                                                   
652 int kvm_vm_smccc_set_attr(struct kvm *kvm, str    
653 {                                                 
654         void __user *uaddr = (void __user *)at    
655                                                   
656         switch (attr->attr) {                     
657         case KVM_ARM_VM_SMCCC_FILTER:             
658                 return kvm_smccc_set_filter(kv    
659         default:                                  
660                 return -ENXIO;                    
661         }                                         
662 }                                                 
663                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php