2015-09-09 160 views
0

Linux已经编有IOMMU功能ON,从dmesg日志,我可以确保:为什么ioctl命令报告“KVM不支持IOMMU”?

[[email protected] vm]# dmesg | grep -e DMAR -e IOMMU 
[ 0.000000] ACPI: DMAR 000000007bfbb000 00368 (v01 HP  03010201 00000002 HPAG 00020000) 
[ 0.000000] DMAR: IOMMU enabled 
[ 0.512361] DMAR: Host address width 44 
[ 0.516675] DMAR: DRHD base: 0x00000093ff8000 flags: 0x0 
[ 0.522664] DMAR: IOMMU 0: reg_base_addr 93ff8000 ver 1:0 cap d2078c106f0466 ecap f020de 
[ 0.531762] DMAR: DRHD base: 0x00000097ff8000 flags: 0x0 
[ 0.537744] DMAR: IOMMU 1: reg_base_addr 97ff8000 ver 1:0 cap d2078c106f0466 ecap f020de 
[ 0.546837] DMAR: DRHD base: 0x0000009bff8000 flags: 0x0 
[ 0.552829] DMAR: IOMMU 2: reg_base_addr 9bff8000 ver 1:0 cap d2078c106f0466 ecap f020de 
[ 0.561922] DMAR: DRHD base: 0x0000009fff8000 flags: 0x0 
[ 0.567904] DMAR: IOMMU 3: reg_base_addr 9fff8000 ver 1:0 cap d2078c106f0466 ecap f020de 
[ 0.576994] DMAR: RMRR base: 0x00000079911000 end: 0x00000079913fff 
[ 0.584038] DMAR: RMRR base: 0x0000007990e000 end: 0x00000079910fff 
[ 0.591079] DMAR: ATSR flags: 0x0 
[ 0.594805] DMAR: ATSR flags: 0x0 
[ 0.598530] DMAR: ATSR flags: 0x0 
[ 0.602255] DMAR: ATSR flags: 0x0 
[ 0.605982] DMAR: RHSA base: 0x00000093ff8000 proximity domain: 0x0 
[ 0.613024] DMAR: RHSA base: 0x00000097ff8000 proximity domain: 0x1 
[ 0.620067] DMAR: RHSA base: 0x0000009bff8000 proximity domain: 0x2 
[ 0.627110] DMAR: RHSA base: 0x0000009fff8000 proximity domain: 0x3 
[ 0.634163] DMAR-IR: IOAPIC id 13 under DRHD base 0x9fff8000 IOMMU 3 
[ 0.641411] DMAR-IR: IOAPIC id 11 under DRHD base 0x9bff8000 IOMMU 2 
[ 0.648647] DMAR-IR: IOAPIC id 12 under DRHD base 0x9bff8000 IOMMU 2 
[ 0.655887] DMAR-IR: IOAPIC id 10 under DRHD base 0x97ff8000 IOMMU 1 
[ 0.663126] DMAR-IR: IOAPIC id 8 under DRHD base 0x93ff8000 IOMMU 0 
[ 0.670264] DMAR-IR: IOAPIC id 9 under DRHD base 0x93ff8000 IOMMU 0 
[ 0.677404] DMAR-IR: HPET id 0 under DRHD base 0x93ff8000 
[ 0.683483] DMAR-IR: Queued invalidation will be enabled to support x2apic and Intr-remapping. 
[ 0.696950] DMAR-IR: Enabled IRQ remapping in x2apic mode 
[ 5.505856] DMAR: dmar3: Using Queued invalidation 
[ 5.511765] DMAR: dmar2: Using Queued invalidation 
[ 5.517667] DMAR: dmar1: Using Queued invalidation 
[ 5.523223] DMAR: dmar0: Using Queued invalidation 
[ 5.528914] DMAR: Setting RMRR: 
[ 5.532484] DMAR: Setting identity map for device 0000:20:1d.0 [0x7990e000 - 0x79910fff] 
[ 5.541659] DMAR: Setting identity map for device 0000:00:1d.0 [0x79911000 - 0x79913fff] 
[ 5.550776] DMAR: Prepare 0-16MiB unity mapping for LPC 
[ 5.556672] DMAR: Setting identity map for device 0000:00:1f.0 [0x0 - 0xffffff] 
[ 5.564908] DMAR: PCI-DMA: Intel(R) Virtualization Technology for Directed I/O 

但执行下面的测试代码:

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <sys/ioctl.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <linux/kvm.h> 

#define KVM_FILE "/dev/kvm" 

int main(void) 
{ 
     int dev; 
     int ret; 

     dev = open(KVM_FILE,O_RDWR|O_NDELAY); 
     ret = ioctl(dev,KVM_CHECK_EXTENSION,KVM_CAP_IOMMU); 
     if(ret != 0) 
       printf("----KVM supports IOMMU (i.e. Intel VT-d or AMD IOMMU).----\n"); 
     else 
       printf("----KVM doesn't support IOMMU (i.e. Intel VT-d or AMD IOMMU).----\n"); 

     return 0; 
} 

输出是:

----KVM doesn't support IOMMU (i.e. Intel VT-d or AMD IOMMU).---- 

我有点困惑,因为从dmesg日志,内核已报告支持IOMMU,为什么ioctl命令假设kernel不支持IOMMU

回答

0

的根源已经找到,需要配置KVM_DEVICE_ASSIGNMENT选项来构建内核。因为在kvm_vm_ioctl_check_extension功能:

#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT 
    case KVM_CAP_IOMMU: 
     r = iommu_present(&pci_bus_type); 
     break; 
#endif 

没有这个选项,函数直接返回0
请参考discussion

0

因为您没有正确检查ioctl返回值。 man ioctl应该可以帮到你。

通常,成功时返回零。一些ioctl()请求使用 返回值作为输出参数,并在 成功时返回非负值。错误时,返回-1,并设置errno适当

由第提到,在KVM_CHECK_EXTENSION IOCTL的特殊情况下将返回正值,如果盖的支持,0,如果不是的话,和-1如果发生错误。

所以代码应该是:

if(ret > 0) 
    printf("----KVM supports IOMMU (i.e. Intel VT-d or AMD IOMMU).----\n"); 
else 
    printf("----KVM doesn't support IOMMU (i.e. Intel VT-d or AMD IOMMU).----\n"); 

你会找到你的内核文件(4.4节)内的多一点细节:https://www.kernel.org/doc/Documentation/virtual/kvm/api.txt

+0

差不多。如果检查成功,KVM_CHECK_EXTENSION ioctl尤其会返回> 0,即存在KVM_CAP_IOMMU。如果不是,则为-1;如果发生错误,则为-1。如果你正在检查一个内核不知道的扩展,它甚至会返回0。所以我怀疑OP的代码结果是不会改变的。感谢, – nos

+0

会纠正这一点。 –

+0

@nos:你能否就这个问题提供一些线索?非常感谢! –