@@ -541,6 +541,21 @@ static void kvm_setup_tss_64bit(struct kvm_vm *vm, struct kvm_segment *segp,
541541 kvm_seg_fill_gdt_64bit (vm , segp );
542542}
543543
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+
544559static void vcpu_setup (struct kvm_vm * vm , struct kvm_vcpu * vcpu )
545560{
546561 struct kvm_sregs sregs ;
@@ -573,6 +588,86 @@ static void vcpu_setup(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
573588 vcpu_sregs_set (vcpu , & sregs );
574589}
575590
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+
576671void kvm_arch_vm_post_create (struct kvm_vm * vm )
577672{
578673 vm_create_irqchip (vm );
@@ -1093,102 +1188,6 @@ void kvm_init_vm_address_properties(struct kvm_vm *vm)
10931188 }
10941189}
10951190
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-
11921191const struct kvm_cpuid_entry2 * get_cpuid_entry (const struct kvm_cpuid2 * cpuid ,
11931192 uint32_t function , uint32_t index )
11941193{
0 commit comments