@@ -541,6 +541,21 @@ static void kvm_setup_tss_64bit(struct kvm_vm *vm, struct kvm_segment *segp,
541
541
kvm_seg_fill_gdt_64bit (vm , segp );
542
542
}
543
543
544
+ void vcpu_init_descriptor_tables (struct kvm_vcpu * vcpu )
545
+ {
546
+ struct kvm_vm * vm = vcpu -> vm ;
547
+ struct kvm_sregs sregs ;
548
+
549
+ vcpu_sregs_get (vcpu , & sregs );
550
+ sregs .idt .base = vm -> arch .idt ;
551
+ sregs .idt .limit = NUM_INTERRUPTS * sizeof (struct idt_entry ) - 1 ;
552
+ sregs .gdt .base = vm -> arch .gdt ;
553
+ sregs .gdt .limit = getpagesize () - 1 ;
554
+ kvm_seg_set_kernel_data_64bit (NULL , DEFAULT_DATA_SELECTOR , & sregs .gs );
555
+ vcpu_sregs_set (vcpu , & sregs );
556
+ * (vm_vaddr_t * )addr_gva2hva (vm , (vm_vaddr_t )(& exception_handlers )) = vm -> handlers ;
557
+ }
558
+
544
559
static void vcpu_setup (struct kvm_vm * vm , struct kvm_vcpu * vcpu )
545
560
{
546
561
struct kvm_sregs sregs ;
@@ -573,6 +588,86 @@ static void vcpu_setup(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
573
588
vcpu_sregs_set (vcpu , & sregs );
574
589
}
575
590
591
+ static void set_idt_entry (struct kvm_vm * vm , int vector , unsigned long addr ,
592
+ int dpl , unsigned short selector )
593
+ {
594
+ struct idt_entry * base =
595
+ (struct idt_entry * )addr_gva2hva (vm , vm -> arch .idt );
596
+ struct idt_entry * e = & base [vector ];
597
+
598
+ memset (e , 0 , sizeof (* e ));
599
+ e -> offset0 = addr ;
600
+ e -> selector = selector ;
601
+ e -> ist = 0 ;
602
+ e -> type = 14 ;
603
+ e -> dpl = dpl ;
604
+ e -> p = 1 ;
605
+ e -> offset1 = addr >> 16 ;
606
+ e -> offset2 = addr >> 32 ;
607
+ }
608
+
609
+ static bool kvm_fixup_exception (struct ex_regs * regs )
610
+ {
611
+ if (regs -> r9 != KVM_EXCEPTION_MAGIC || regs -> rip != regs -> r10 )
612
+ return false;
613
+
614
+ if (regs -> vector == DE_VECTOR )
615
+ return false;
616
+
617
+ regs -> rip = regs -> r11 ;
618
+ regs -> r9 = regs -> vector ;
619
+ regs -> r10 = regs -> error_code ;
620
+ return true;
621
+ }
622
+
623
+ void route_exception (struct ex_regs * regs )
624
+ {
625
+ typedef void (* handler )(struct ex_regs * );
626
+ handler * handlers = (handler * )exception_handlers ;
627
+
628
+ if (handlers && handlers [regs -> vector ]) {
629
+ handlers [regs -> vector ](regs );
630
+ return ;
631
+ }
632
+
633
+ if (kvm_fixup_exception (regs ))
634
+ return ;
635
+
636
+ ucall_assert (UCALL_UNHANDLED ,
637
+ "Unhandled exception in guest" , __FILE__ , __LINE__ ,
638
+ "Unhandled exception '0x%lx' at guest RIP '0x%lx'" ,
639
+ regs -> vector , regs -> rip );
640
+ }
641
+
642
+ void vm_init_descriptor_tables (struct kvm_vm * vm )
643
+ {
644
+ extern void * idt_handlers ;
645
+ int i ;
646
+
647
+ vm -> arch .idt = __vm_vaddr_alloc_page (vm , MEM_REGION_DATA );
648
+ vm -> handlers = __vm_vaddr_alloc_page (vm , MEM_REGION_DATA );
649
+ /* Handlers have the same address in both address spaces.*/
650
+ for (i = 0 ; i < NUM_INTERRUPTS ; i ++ )
651
+ set_idt_entry (vm , i , (unsigned long )(& idt_handlers )[i ], 0 ,
652
+ DEFAULT_CODE_SELECTOR );
653
+ }
654
+
655
+ void vm_install_exception_handler (struct kvm_vm * vm , int vector ,
656
+ void (* handler )(struct ex_regs * ))
657
+ {
658
+ vm_vaddr_t * handlers = (vm_vaddr_t * )addr_gva2hva (vm , vm -> handlers );
659
+
660
+ handlers [vector ] = (vm_vaddr_t )handler ;
661
+ }
662
+
663
+ void assert_on_unhandled_exception (struct kvm_vcpu * vcpu )
664
+ {
665
+ struct ucall uc ;
666
+
667
+ if (get_ucall (vcpu , & uc ) == UCALL_UNHANDLED )
668
+ REPORT_GUEST_ASSERT (uc );
669
+ }
670
+
576
671
void kvm_arch_vm_post_create (struct kvm_vm * vm )
577
672
{
578
673
vm_create_irqchip (vm );
@@ -1093,102 +1188,6 @@ void kvm_init_vm_address_properties(struct kvm_vm *vm)
1093
1188
}
1094
1189
}
1095
1190
1096
- static void set_idt_entry (struct kvm_vm * vm , int vector , unsigned long addr ,
1097
- int dpl , unsigned short selector )
1098
- {
1099
- struct idt_entry * base =
1100
- (struct idt_entry * )addr_gva2hva (vm , vm -> arch .idt );
1101
- struct idt_entry * e = & base [vector ];
1102
-
1103
- memset (e , 0 , sizeof (* e ));
1104
- e -> offset0 = addr ;
1105
- e -> selector = selector ;
1106
- e -> ist = 0 ;
1107
- e -> type = 14 ;
1108
- e -> dpl = dpl ;
1109
- e -> p = 1 ;
1110
- e -> offset1 = addr >> 16 ;
1111
- e -> offset2 = addr >> 32 ;
1112
- }
1113
-
1114
-
1115
- static bool kvm_fixup_exception (struct ex_regs * regs )
1116
- {
1117
- if (regs -> r9 != KVM_EXCEPTION_MAGIC || regs -> rip != regs -> r10 )
1118
- return false;
1119
-
1120
- if (regs -> vector == DE_VECTOR )
1121
- return false;
1122
-
1123
- regs -> rip = regs -> r11 ;
1124
- regs -> r9 = regs -> vector ;
1125
- regs -> r10 = regs -> error_code ;
1126
- return true;
1127
- }
1128
-
1129
- void route_exception (struct ex_regs * regs )
1130
- {
1131
- typedef void (* handler )(struct ex_regs * );
1132
- handler * handlers = (handler * )exception_handlers ;
1133
-
1134
- if (handlers && handlers [regs -> vector ]) {
1135
- handlers [regs -> vector ](regs );
1136
- return ;
1137
- }
1138
-
1139
- if (kvm_fixup_exception (regs ))
1140
- return ;
1141
-
1142
- ucall_assert (UCALL_UNHANDLED ,
1143
- "Unhandled exception in guest" , __FILE__ , __LINE__ ,
1144
- "Unhandled exception '0x%lx' at guest RIP '0x%lx'" ,
1145
- regs -> vector , regs -> rip );
1146
- }
1147
-
1148
- void vm_init_descriptor_tables (struct kvm_vm * vm )
1149
- {
1150
- extern void * idt_handlers ;
1151
- int i ;
1152
-
1153
- vm -> arch .idt = __vm_vaddr_alloc_page (vm , MEM_REGION_DATA );
1154
- vm -> handlers = __vm_vaddr_alloc_page (vm , MEM_REGION_DATA );
1155
- /* Handlers have the same address in both address spaces.*/
1156
- for (i = 0 ; i < NUM_INTERRUPTS ; i ++ )
1157
- set_idt_entry (vm , i , (unsigned long )(& idt_handlers )[i ], 0 ,
1158
- DEFAULT_CODE_SELECTOR );
1159
- }
1160
-
1161
- void vcpu_init_descriptor_tables (struct kvm_vcpu * vcpu )
1162
- {
1163
- struct kvm_vm * vm = vcpu -> vm ;
1164
- struct kvm_sregs sregs ;
1165
-
1166
- vcpu_sregs_get (vcpu , & sregs );
1167
- sregs .idt .base = vm -> arch .idt ;
1168
- sregs .idt .limit = NUM_INTERRUPTS * sizeof (struct idt_entry ) - 1 ;
1169
- sregs .gdt .base = vm -> arch .gdt ;
1170
- sregs .gdt .limit = getpagesize () - 1 ;
1171
- kvm_seg_set_kernel_data_64bit (NULL , DEFAULT_DATA_SELECTOR , & sregs .gs );
1172
- vcpu_sregs_set (vcpu , & sregs );
1173
- * (vm_vaddr_t * )addr_gva2hva (vm , (vm_vaddr_t )(& exception_handlers )) = vm -> handlers ;
1174
- }
1175
-
1176
- void vm_install_exception_handler (struct kvm_vm * vm , int vector ,
1177
- void (* handler )(struct ex_regs * ))
1178
- {
1179
- vm_vaddr_t * handlers = (vm_vaddr_t * )addr_gva2hva (vm , vm -> handlers );
1180
-
1181
- handlers [vector ] = (vm_vaddr_t )handler ;
1182
- }
1183
-
1184
- void assert_on_unhandled_exception (struct kvm_vcpu * vcpu )
1185
- {
1186
- struct ucall uc ;
1187
-
1188
- if (get_ucall (vcpu , & uc ) == UCALL_UNHANDLED )
1189
- REPORT_GUEST_ASSERT (uc );
1190
- }
1191
-
1192
1191
const struct kvm_cpuid_entry2 * get_cpuid_entry (const struct kvm_cpuid2 * cpuid ,
1193
1192
uint32_t function , uint32_t index )
1194
1193
{
0 commit comments