ACPI: APEI: Fix integer overflow in ghes_estatus_pool_init()
[sfrench/cifs-2.6.git] / tools / testing / selftests / kvm / x86_64 / hyperv_features.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2021, Red Hat, Inc.
4  *
5  * Tests for Hyper-V features enablement
6  */
7 #include <asm/kvm_para.h>
8 #include <linux/kvm_para.h>
9 #include <stdint.h>
10
11 #include "test_util.h"
12 #include "kvm_util.h"
13 #include "processor.h"
14 #include "hyperv.h"
15
16 #define LINUX_OS_ID ((u64)0x8100 << 48)
17
18 static inline uint8_t hypercall(u64 control, vm_vaddr_t input_address,
19                                 vm_vaddr_t output_address, uint64_t *hv_status)
20 {
21         uint8_t vector;
22
23         /* Note both the hypercall and the "asm safe" clobber r9-r11. */
24         asm volatile("mov %[output_address], %%r8\n\t"
25                      KVM_ASM_SAFE("vmcall")
26                      : "=a" (*hv_status),
27                        "+c" (control), "+d" (input_address),
28                        KVM_ASM_SAFE_OUTPUTS(vector)
29                      : [output_address] "r"(output_address)
30                      : "cc", "memory", "r8", KVM_ASM_SAFE_CLOBBERS);
31         return vector;
32 }
33
34 struct msr_data {
35         uint32_t idx;
36         bool available;
37         bool write;
38         u64 write_val;
39 };
40
41 struct hcall_data {
42         uint64_t control;
43         uint64_t expect;
44         bool ud_expected;
45 };
46
47 static void guest_msr(struct msr_data *msr)
48 {
49         uint64_t ignored;
50         uint8_t vector;
51
52         GUEST_ASSERT(msr->idx);
53
54         if (!msr->write)
55                 vector = rdmsr_safe(msr->idx, &ignored);
56         else
57                 vector = wrmsr_safe(msr->idx, msr->write_val);
58
59         if (msr->available)
60                 GUEST_ASSERT_2(!vector, msr->idx, vector);
61         else
62                 GUEST_ASSERT_2(vector == GP_VECTOR, msr->idx, vector);
63         GUEST_DONE();
64 }
65
66 static void guest_hcall(vm_vaddr_t pgs_gpa, struct hcall_data *hcall)
67 {
68         u64 res, input, output;
69         uint8_t vector;
70
71         GUEST_ASSERT(hcall->control);
72
73         wrmsr(HV_X64_MSR_GUEST_OS_ID, LINUX_OS_ID);
74         wrmsr(HV_X64_MSR_HYPERCALL, pgs_gpa);
75
76         if (!(hcall->control & HV_HYPERCALL_FAST_BIT)) {
77                 input = pgs_gpa;
78                 output = pgs_gpa + 4096;
79         } else {
80                 input = output = 0;
81         }
82
83         vector = hypercall(hcall->control, input, output, &res);
84         if (hcall->ud_expected)
85                 GUEST_ASSERT_2(vector == UD_VECTOR, hcall->control, vector);
86         else
87                 GUEST_ASSERT_2(!vector, hcall->control, vector);
88
89         GUEST_ASSERT_2(!hcall->ud_expected || res == hcall->expect,
90                         hcall->expect, res);
91         GUEST_DONE();
92 }
93
94 static void vcpu_reset_hv_cpuid(struct kvm_vcpu *vcpu)
95 {
96         /*
97          * Enable all supported Hyper-V features, then clear the leafs holding
98          * the features that will be tested one by one.
99          */
100         vcpu_set_hv_cpuid(vcpu);
101
102         vcpu_clear_cpuid_entry(vcpu, HYPERV_CPUID_FEATURES);
103         vcpu_clear_cpuid_entry(vcpu, HYPERV_CPUID_ENLIGHTMENT_INFO);
104         vcpu_clear_cpuid_entry(vcpu, HYPERV_CPUID_SYNDBG_PLATFORM_CAPABILITIES);
105 }
106
107 static void guest_test_msrs_access(void)
108 {
109         struct kvm_cpuid2 *prev_cpuid = NULL;
110         struct kvm_cpuid_entry2 *feat, *dbg;
111         struct kvm_vcpu *vcpu;
112         struct kvm_run *run;
113         struct kvm_vm *vm;
114         struct ucall uc;
115         int stage = 0;
116         vm_vaddr_t msr_gva;
117         struct msr_data *msr;
118
119         while (true) {
120                 vm = vm_create_with_one_vcpu(&vcpu, guest_msr);
121
122                 msr_gva = vm_vaddr_alloc_page(vm);
123                 memset(addr_gva2hva(vm, msr_gva), 0x0, getpagesize());
124                 msr = addr_gva2hva(vm, msr_gva);
125
126                 vcpu_args_set(vcpu, 1, msr_gva);
127                 vcpu_enable_cap(vcpu, KVM_CAP_HYPERV_ENFORCE_CPUID, 1);
128
129                 if (!prev_cpuid) {
130                         vcpu_reset_hv_cpuid(vcpu);
131
132                         prev_cpuid = allocate_kvm_cpuid2(vcpu->cpuid->nent);
133                 } else {
134                         vcpu_init_cpuid(vcpu, prev_cpuid);
135                 }
136
137                 feat = vcpu_get_cpuid_entry(vcpu, HYPERV_CPUID_FEATURES);
138                 dbg = vcpu_get_cpuid_entry(vcpu, HYPERV_CPUID_SYNDBG_PLATFORM_CAPABILITIES);
139
140                 vm_init_descriptor_tables(vm);
141                 vcpu_init_descriptor_tables(vcpu);
142
143                 run = vcpu->run;
144
145                 /* TODO: Make this entire test easier to maintain. */
146                 if (stage >= 21)
147                         vcpu_enable_cap(vcpu, KVM_CAP_HYPERV_SYNIC2, 0);
148
149                 switch (stage) {
150                 case 0:
151                         /*
152                          * Only available when Hyper-V identification is set
153                          */
154                         msr->idx = HV_X64_MSR_GUEST_OS_ID;
155                         msr->write = 0;
156                         msr->available = 0;
157                         break;
158                 case 1:
159                         msr->idx = HV_X64_MSR_HYPERCALL;
160                         msr->write = 0;
161                         msr->available = 0;
162                         break;
163                 case 2:
164                         feat->eax |= HV_MSR_HYPERCALL_AVAILABLE;
165                         /*
166                          * HV_X64_MSR_GUEST_OS_ID has to be written first to make
167                          * HV_X64_MSR_HYPERCALL available.
168                          */
169                         msr->idx = HV_X64_MSR_GUEST_OS_ID;
170                         msr->write = 1;
171                         msr->write_val = LINUX_OS_ID;
172                         msr->available = 1;
173                         break;
174                 case 3:
175                         msr->idx = HV_X64_MSR_GUEST_OS_ID;
176                         msr->write = 0;
177                         msr->available = 1;
178                         break;
179                 case 4:
180                         msr->idx = HV_X64_MSR_HYPERCALL;
181                         msr->write = 0;
182                         msr->available = 1;
183                         break;
184
185                 case 5:
186                         msr->idx = HV_X64_MSR_VP_RUNTIME;
187                         msr->write = 0;
188                         msr->available = 0;
189                         break;
190                 case 6:
191                         feat->eax |= HV_MSR_VP_RUNTIME_AVAILABLE;
192                         msr->idx = HV_X64_MSR_VP_RUNTIME;
193                         msr->write = 0;
194                         msr->available = 1;
195                         break;
196                 case 7:
197                         /* Read only */
198                         msr->idx = HV_X64_MSR_VP_RUNTIME;
199                         msr->write = 1;
200                         msr->write_val = 1;
201                         msr->available = 0;
202                         break;
203
204                 case 8:
205                         msr->idx = HV_X64_MSR_TIME_REF_COUNT;
206                         msr->write = 0;
207                         msr->available = 0;
208                         break;
209                 case 9:
210                         feat->eax |= HV_MSR_TIME_REF_COUNT_AVAILABLE;
211                         msr->idx = HV_X64_MSR_TIME_REF_COUNT;
212                         msr->write = 0;
213                         msr->available = 1;
214                         break;
215                 case 10:
216                         /* Read only */
217                         msr->idx = HV_X64_MSR_TIME_REF_COUNT;
218                         msr->write = 1;
219                         msr->write_val = 1;
220                         msr->available = 0;
221                         break;
222
223                 case 11:
224                         msr->idx = HV_X64_MSR_VP_INDEX;
225                         msr->write = 0;
226                         msr->available = 0;
227                         break;
228                 case 12:
229                         feat->eax |= HV_MSR_VP_INDEX_AVAILABLE;
230                         msr->idx = HV_X64_MSR_VP_INDEX;
231                         msr->write = 0;
232                         msr->available = 1;
233                         break;
234                 case 13:
235                         /* Read only */
236                         msr->idx = HV_X64_MSR_VP_INDEX;
237                         msr->write = 1;
238                         msr->write_val = 1;
239                         msr->available = 0;
240                         break;
241
242                 case 14:
243                         msr->idx = HV_X64_MSR_RESET;
244                         msr->write = 0;
245                         msr->available = 0;
246                         break;
247                 case 15:
248                         feat->eax |= HV_MSR_RESET_AVAILABLE;
249                         msr->idx = HV_X64_MSR_RESET;
250                         msr->write = 0;
251                         msr->available = 1;
252                         break;
253                 case 16:
254                         msr->idx = HV_X64_MSR_RESET;
255                         msr->write = 1;
256                         msr->write_val = 0;
257                         msr->available = 1;
258                         break;
259
260                 case 17:
261                         msr->idx = HV_X64_MSR_REFERENCE_TSC;
262                         msr->write = 0;
263                         msr->available = 0;
264                         break;
265                 case 18:
266                         feat->eax |= HV_MSR_REFERENCE_TSC_AVAILABLE;
267                         msr->idx = HV_X64_MSR_REFERENCE_TSC;
268                         msr->write = 0;
269                         msr->available = 1;
270                         break;
271                 case 19:
272                         msr->idx = HV_X64_MSR_REFERENCE_TSC;
273                         msr->write = 1;
274                         msr->write_val = 0;
275                         msr->available = 1;
276                         break;
277
278                 case 20:
279                         msr->idx = HV_X64_MSR_EOM;
280                         msr->write = 0;
281                         msr->available = 0;
282                         break;
283                 case 21:
284                         /*
285                          * Remains unavailable even with KVM_CAP_HYPERV_SYNIC2
286                          * capability enabled and guest visible CPUID bit unset.
287                          */
288                         msr->idx = HV_X64_MSR_EOM;
289                         msr->write = 0;
290                         msr->available = 0;
291                         break;
292                 case 22:
293                         feat->eax |= HV_MSR_SYNIC_AVAILABLE;
294                         msr->idx = HV_X64_MSR_EOM;
295                         msr->write = 0;
296                         msr->available = 1;
297                         break;
298                 case 23:
299                         msr->idx = HV_X64_MSR_EOM;
300                         msr->write = 1;
301                         msr->write_val = 0;
302                         msr->available = 1;
303                         break;
304
305                 case 24:
306                         msr->idx = HV_X64_MSR_STIMER0_CONFIG;
307                         msr->write = 0;
308                         msr->available = 0;
309                         break;
310                 case 25:
311                         feat->eax |= HV_MSR_SYNTIMER_AVAILABLE;
312                         msr->idx = HV_X64_MSR_STIMER0_CONFIG;
313                         msr->write = 0;
314                         msr->available = 1;
315                         break;
316                 case 26:
317                         msr->idx = HV_X64_MSR_STIMER0_CONFIG;
318                         msr->write = 1;
319                         msr->write_val = 0;
320                         msr->available = 1;
321                         break;
322                 case 27:
323                         /* Direct mode test */
324                         msr->idx = HV_X64_MSR_STIMER0_CONFIG;
325                         msr->write = 1;
326                         msr->write_val = 1 << 12;
327                         msr->available = 0;
328                         break;
329                 case 28:
330                         feat->edx |= HV_STIMER_DIRECT_MODE_AVAILABLE;
331                         msr->idx = HV_X64_MSR_STIMER0_CONFIG;
332                         msr->write = 1;
333                         msr->write_val = 1 << 12;
334                         msr->available = 1;
335                         break;
336
337                 case 29:
338                         msr->idx = HV_X64_MSR_EOI;
339                         msr->write = 0;
340                         msr->available = 0;
341                         break;
342                 case 30:
343                         feat->eax |= HV_MSR_APIC_ACCESS_AVAILABLE;
344                         msr->idx = HV_X64_MSR_EOI;
345                         msr->write = 1;
346                         msr->write_val = 1;
347                         msr->available = 1;
348                         break;
349
350                 case 31:
351                         msr->idx = HV_X64_MSR_TSC_FREQUENCY;
352                         msr->write = 0;
353                         msr->available = 0;
354                         break;
355                 case 32:
356                         feat->eax |= HV_ACCESS_FREQUENCY_MSRS;
357                         msr->idx = HV_X64_MSR_TSC_FREQUENCY;
358                         msr->write = 0;
359                         msr->available = 1;
360                         break;
361                 case 33:
362                         /* Read only */
363                         msr->idx = HV_X64_MSR_TSC_FREQUENCY;
364                         msr->write = 1;
365                         msr->write_val = 1;
366                         msr->available = 0;
367                         break;
368
369                 case 34:
370                         msr->idx = HV_X64_MSR_REENLIGHTENMENT_CONTROL;
371                         msr->write = 0;
372                         msr->available = 0;
373                         break;
374                 case 35:
375                         feat->eax |= HV_ACCESS_REENLIGHTENMENT;
376                         msr->idx = HV_X64_MSR_REENLIGHTENMENT_CONTROL;
377                         msr->write = 0;
378                         msr->available = 1;
379                         break;
380                 case 36:
381                         msr->idx = HV_X64_MSR_REENLIGHTENMENT_CONTROL;
382                         msr->write = 1;
383                         msr->write_val = 1;
384                         msr->available = 1;
385                         break;
386                 case 37:
387                         /* Can only write '0' */
388                         msr->idx = HV_X64_MSR_TSC_EMULATION_STATUS;
389                         msr->write = 1;
390                         msr->write_val = 1;
391                         msr->available = 0;
392                         break;
393
394                 case 38:
395                         msr->idx = HV_X64_MSR_CRASH_P0;
396                         msr->write = 0;
397                         msr->available = 0;
398                         break;
399                 case 39:
400                         feat->edx |= HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE;
401                         msr->idx = HV_X64_MSR_CRASH_P0;
402                         msr->write = 0;
403                         msr->available = 1;
404                         break;
405                 case 40:
406                         msr->idx = HV_X64_MSR_CRASH_P0;
407                         msr->write = 1;
408                         msr->write_val = 1;
409                         msr->available = 1;
410                         break;
411
412                 case 41:
413                         msr->idx = HV_X64_MSR_SYNDBG_STATUS;
414                         msr->write = 0;
415                         msr->available = 0;
416                         break;
417                 case 42:
418                         feat->edx |= HV_FEATURE_DEBUG_MSRS_AVAILABLE;
419                         dbg->eax |= HV_X64_SYNDBG_CAP_ALLOW_KERNEL_DEBUGGING;
420                         msr->idx = HV_X64_MSR_SYNDBG_STATUS;
421                         msr->write = 0;
422                         msr->available = 1;
423                         break;
424                 case 43:
425                         msr->idx = HV_X64_MSR_SYNDBG_STATUS;
426                         msr->write = 1;
427                         msr->write_val = 0;
428                         msr->available = 1;
429                         break;
430
431                 case 44:
432                         kvm_vm_free(vm);
433                         return;
434                 }
435
436                 vcpu_set_cpuid(vcpu);
437
438                 memcpy(prev_cpuid, vcpu->cpuid, kvm_cpuid2_size(vcpu->cpuid->nent));
439
440                 pr_debug("Stage %d: testing msr: 0x%x for %s\n", stage,
441                          msr->idx, msr->write ? "write" : "read");
442
443                 vcpu_run(vcpu);
444                 TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
445                             "unexpected exit reason: %u (%s)",
446                             run->exit_reason, exit_reason_str(run->exit_reason));
447
448                 switch (get_ucall(vcpu, &uc)) {
449                 case UCALL_ABORT:
450                         REPORT_GUEST_ASSERT_2(uc, "MSR = %lx, vector = %lx");
451                         return;
452                 case UCALL_DONE:
453                         break;
454                 default:
455                         TEST_FAIL("Unhandled ucall: %ld", uc.cmd);
456                         return;
457                 }
458
459                 stage++;
460                 kvm_vm_free(vm);
461         }
462 }
463
464 static void guest_test_hcalls_access(void)
465 {
466         struct kvm_cpuid_entry2 *feat, *recomm, *dbg;
467         struct kvm_cpuid2 *prev_cpuid = NULL;
468         struct kvm_vcpu *vcpu;
469         struct kvm_run *run;
470         struct kvm_vm *vm;
471         struct ucall uc;
472         int stage = 0;
473         vm_vaddr_t hcall_page, hcall_params;
474         struct hcall_data *hcall;
475
476         while (true) {
477                 vm = vm_create_with_one_vcpu(&vcpu, guest_hcall);
478
479                 vm_init_descriptor_tables(vm);
480                 vcpu_init_descriptor_tables(vcpu);
481
482                 /* Hypercall input/output */
483                 hcall_page = vm_vaddr_alloc_pages(vm, 2);
484                 memset(addr_gva2hva(vm, hcall_page), 0x0, 2 * getpagesize());
485
486                 hcall_params = vm_vaddr_alloc_page(vm);
487                 memset(addr_gva2hva(vm, hcall_params), 0x0, getpagesize());
488                 hcall = addr_gva2hva(vm, hcall_params);
489
490                 vcpu_args_set(vcpu, 2, addr_gva2gpa(vm, hcall_page), hcall_params);
491                 vcpu_enable_cap(vcpu, KVM_CAP_HYPERV_ENFORCE_CPUID, 1);
492
493                 if (!prev_cpuid) {
494                         vcpu_reset_hv_cpuid(vcpu);
495
496                         prev_cpuid = allocate_kvm_cpuid2(vcpu->cpuid->nent);
497                 } else {
498                         vcpu_init_cpuid(vcpu, prev_cpuid);
499                 }
500
501                 feat = vcpu_get_cpuid_entry(vcpu, HYPERV_CPUID_FEATURES);
502                 recomm = vcpu_get_cpuid_entry(vcpu, HYPERV_CPUID_ENLIGHTMENT_INFO);
503                 dbg = vcpu_get_cpuid_entry(vcpu, HYPERV_CPUID_SYNDBG_PLATFORM_CAPABILITIES);
504
505                 run = vcpu->run;
506
507                 switch (stage) {
508                 case 0:
509                         feat->eax |= HV_MSR_HYPERCALL_AVAILABLE;
510                         hcall->control = 0xdeadbeef;
511                         hcall->expect = HV_STATUS_INVALID_HYPERCALL_CODE;
512                         break;
513
514                 case 1:
515                         hcall->control = HVCALL_POST_MESSAGE;
516                         hcall->expect = HV_STATUS_ACCESS_DENIED;
517                         break;
518                 case 2:
519                         feat->ebx |= HV_POST_MESSAGES;
520                         hcall->control = HVCALL_POST_MESSAGE;
521                         hcall->expect = HV_STATUS_INVALID_HYPERCALL_INPUT;
522                         break;
523
524                 case 3:
525                         hcall->control = HVCALL_SIGNAL_EVENT;
526                         hcall->expect = HV_STATUS_ACCESS_DENIED;
527                         break;
528                 case 4:
529                         feat->ebx |= HV_SIGNAL_EVENTS;
530                         hcall->control = HVCALL_SIGNAL_EVENT;
531                         hcall->expect = HV_STATUS_INVALID_HYPERCALL_INPUT;
532                         break;
533
534                 case 5:
535                         hcall->control = HVCALL_RESET_DEBUG_SESSION;
536                         hcall->expect = HV_STATUS_INVALID_HYPERCALL_CODE;
537                         break;
538                 case 6:
539                         dbg->eax |= HV_X64_SYNDBG_CAP_ALLOW_KERNEL_DEBUGGING;
540                         hcall->control = HVCALL_RESET_DEBUG_SESSION;
541                         hcall->expect = HV_STATUS_ACCESS_DENIED;
542                         break;
543                 case 7:
544                         feat->ebx |= HV_DEBUGGING;
545                         hcall->control = HVCALL_RESET_DEBUG_SESSION;
546                         hcall->expect = HV_STATUS_OPERATION_DENIED;
547                         break;
548
549                 case 8:
550                         hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE;
551                         hcall->expect = HV_STATUS_ACCESS_DENIED;
552                         break;
553                 case 9:
554                         recomm->eax |= HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED;
555                         hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE;
556                         hcall->expect = HV_STATUS_SUCCESS;
557                         break;
558                 case 10:
559                         hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX;
560                         hcall->expect = HV_STATUS_ACCESS_DENIED;
561                         break;
562                 case 11:
563                         recomm->eax |= HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED;
564                         hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX;
565                         hcall->expect = HV_STATUS_SUCCESS;
566                         break;
567
568                 case 12:
569                         hcall->control = HVCALL_SEND_IPI;
570                         hcall->expect = HV_STATUS_ACCESS_DENIED;
571                         break;
572                 case 13:
573                         recomm->eax |= HV_X64_CLUSTER_IPI_RECOMMENDED;
574                         hcall->control = HVCALL_SEND_IPI;
575                         hcall->expect = HV_STATUS_INVALID_HYPERCALL_INPUT;
576                         break;
577                 case 14:
578                         /* Nothing in 'sparse banks' -> success */
579                         hcall->control = HVCALL_SEND_IPI_EX;
580                         hcall->expect = HV_STATUS_SUCCESS;
581                         break;
582
583                 case 15:
584                         hcall->control = HVCALL_NOTIFY_LONG_SPIN_WAIT;
585                         hcall->expect = HV_STATUS_ACCESS_DENIED;
586                         break;
587                 case 16:
588                         recomm->ebx = 0xfff;
589                         hcall->control = HVCALL_NOTIFY_LONG_SPIN_WAIT;
590                         hcall->expect = HV_STATUS_SUCCESS;
591                         break;
592                 case 17:
593                         /* XMM fast hypercall */
594                         hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE | HV_HYPERCALL_FAST_BIT;
595                         hcall->ud_expected = true;
596                         break;
597                 case 18:
598                         feat->edx |= HV_X64_HYPERCALL_XMM_INPUT_AVAILABLE;
599                         hcall->control = HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE | HV_HYPERCALL_FAST_BIT;
600                         hcall->ud_expected = false;
601                         hcall->expect = HV_STATUS_SUCCESS;
602                         break;
603                 case 19:
604                         kvm_vm_free(vm);
605                         return;
606                 }
607
608                 vcpu_set_cpuid(vcpu);
609
610                 memcpy(prev_cpuid, vcpu->cpuid, kvm_cpuid2_size(vcpu->cpuid->nent));
611
612                 pr_debug("Stage %d: testing hcall: 0x%lx\n", stage, hcall->control);
613
614                 vcpu_run(vcpu);
615                 TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
616                             "unexpected exit reason: %u (%s)",
617                             run->exit_reason, exit_reason_str(run->exit_reason));
618
619                 switch (get_ucall(vcpu, &uc)) {
620                 case UCALL_ABORT:
621                         REPORT_GUEST_ASSERT_2(uc, "arg1 = %lx, arg2 = %lx");
622                         return;
623                 case UCALL_DONE:
624                         break;
625                 default:
626                         TEST_FAIL("Unhandled ucall: %ld", uc.cmd);
627                         return;
628                 }
629
630                 stage++;
631                 kvm_vm_free(vm);
632         }
633 }
634
635 int main(void)
636 {
637         pr_info("Testing access to Hyper-V specific MSRs\n");
638         guest_test_msrs_access();
639
640         pr_info("Testing access to Hyper-V hypercalls\n");
641         guest_test_hcalls_access();
642 }