Constructs a routing entry
(&self, gsi: u32, config: &InterruptSourceConfig)
| 920 | /// Constructs a routing entry |
| 921 | /// |
| 922 | fn make_routing_entry(&self, gsi: u32, config: &InterruptSourceConfig) -> IrqRoutingEntry { |
| 923 | match &config { |
| 924 | InterruptSourceConfig::MsiIrq(cfg) => { |
| 925 | let mut kvm_route = kvm_irq_routing_entry { |
| 926 | gsi, |
| 927 | type_: KVM_IRQ_ROUTING_MSI, |
| 928 | ..Default::default() |
| 929 | }; |
| 930 | |
| 931 | let (address_lo, address_hi) = |
| 932 | Self::translate_msi_ext_dest_id(cfg.low_addr, cfg.high_addr); |
| 933 | |
| 934 | kvm_route.u.msi.address_lo = address_lo; |
| 935 | kvm_route.u.msi.address_hi = address_hi; |
| 936 | |
| 937 | kvm_route.u.msi.data = cfg.data; |
| 938 | |
| 939 | if self.check_extension(crate::kvm::Cap::MsiDevid) { |
| 940 | // On AArch64, there is limitation on the range of the 'devid', |
| 941 | // it cannot be greater than 65536 (the max of u16). |
| 942 | // |
| 943 | // BDF cannot be used directly, because 'segment' is in high |
| 944 | // 16 bits. The layout of the u32 BDF is: |
| 945 | // |---- 16 bits ----|-- 8 bits --|-- 5 bits --|-- 3 bits --| |
| 946 | // | segment | bus | device | function | |
| 947 | // |
| 948 | // Now that we support 1 bus only in a segment, we can build a |
| 949 | // 'devid' by replacing the 'bus' bits with the low 8 bits of |
| 950 | // 'segment' data. |
| 951 | // This way we can resolve the range checking problem and give |
| 952 | // different `devid` to all the devices. Limitation is that at |
| 953 | // most 256 segments can be supported. |
| 954 | // |
| 955 | let modified_devid = ((cfg.devid & 0x00ff_0000) >> 8) | cfg.devid & 0xff; |
| 956 | |
| 957 | kvm_route.flags = KVM_MSI_VALID_DEVID; |
| 958 | kvm_route.u.msi.__bindgen_anon_1.devid = modified_devid; |
| 959 | } |
| 960 | kvm_route.into() |
| 961 | } |
| 962 | InterruptSourceConfig::LegacyIrq(cfg) => { |
| 963 | let mut kvm_route = kvm_irq_routing_entry { |
| 964 | gsi, |
| 965 | type_: KVM_IRQ_ROUTING_IRQCHIP, |
| 966 | ..Default::default() |
| 967 | }; |
| 968 | kvm_route.u.irqchip.irqchip = cfg.irqchip; |
| 969 | kvm_route.u.irqchip.pin = cfg.pin; |
| 970 | |
| 971 | kvm_route.into() |
| 972 | } |
| 973 | } |
| 974 | } |
| 975 | |
| 976 | /// |
| 977 | /// Sets the GSI routing table entries, overwriting any previously set |