uint16_t msix_t::setup_vector(uint8_t cpu, uint8_t intr) { // find free table entry uint16_t vec; for (vec = 0; vec < this->vectors(); vec++) { // read data register auto reg = get_entry(vec, ENT_MSG_DATA); if ((mm_read(reg) & 0xff) == 0) break; } assert (vec != this->vectors()); // use free table entry INFO2("MSI-X vector %u pointing to cpu %u intr %u", vec, cpu, intr); // mask entry mask_entry(vec); mm_write(get_entry(vec, ENT_MSG_ADDR), msix_addr_single_cpu(cpu)); mm_write(get_entry(vec, ENT_MSG_UPPER), 0x0); mm_write(get_entry(vec, ENT_MSG_DATA), msix_data_single_vector(intr)); // unmask entry unmask_entry(vec); // return it return vec; }
msix_t::msix_t(PCI_Device& device) : dev(device) { // get capability structure auto cap = dev.msix_cap(); assert(cap >= 0x40); // read message control bits uint16_t func = dev.read16(cap + 2); /// if MSIX was already enabled, avoid validating func if ((func & MSIX_ENABLE) == 0) assert(func < 0x1000 && "Invalid MSI-X func read"); // enable msix and mask all vectors func |= MSIX_ENABLE | MSIX_FUNC_MASK; dev.write16(cap + 2, func); // get the physical addresses of the // MSI-X table and pending bit array (PBA) this->table_addr = get_bar_paddr(cap + 4); this->pba_addr = get_bar_paddr(cap + 8); // get number of vectors we can get notifications from this->vector_cnt = (func & MSIX_TBL_SIZE) + 1; if (vector_cnt > 16) { printf("table addr: %#x pba addr: %#x vectors: %u\n", table_addr, pba_addr, vectors()); assert(vectors() <= 16 && "Unreasonably many MSI-X vectors"); } // reset all entries for (size_t i = 0; i < this->vectors(); i++) { mask_entry(i); zero_entry(i); } // unmask vectors func &= ~MSIX_FUNC_MASK; // write back message control bits dev.write16(cap + 2, func); }
int checkHostAccessControl( const std::string& _user_name, const std::string& _host_client, const std::string& _groups_name ) { typedef irods::configuration_parser::object_t object_t; typedef irods::configuration_parser::array_t array_t; namespace ip = boost::asio::ip; std::string cfg_file; irods::error ret = irods::get_full_path_for_config_file( HOST_ACCESS_CONTROL_FILE, cfg_file ); if ( !ret.ok() ) { irods::log( PASS( ret ) ); return ret.code(); } irods::configuration_parser cfg; ret = cfg.load( cfg_file ); if( !ret.ok() ) { irods::log( PASS( ret ) ); return ret.code(); } std::vector< std::string > group_list; boost::split( group_list, _groups_name, boost::is_any_of( "\t " ), boost::token_compress_on ); array_t access_entries; ret = cfg.get< array_t > ( "access_entries", access_entries ); if( !ret.ok() ) { irods::log( PASS( ret ) ); return ret.code(); } for( size_t ae_idx = 0; ae_idx < access_entries.size(); ++ae_idx ) { object_t obj = access_entries[ ae_idx ]; std::string user; ret = obj.get< std::string >( "user", user ); if( !ret.ok() ) { irods::log( PASS( ret ) ); continue; } std::string group; ret = obj.get< std::string >( "group", group ); if( !ret.ok() ) { irods::log( PASS( ret ) ); continue; } std::string addy; ret = obj.get< std::string >( "address", addy ); if( !ret.ok() ) { irods::log( PASS( ret ) ); continue; } std::string mask; ret = obj.get< std::string >( "mask", mask ); if( !ret.ok() ) { irods::log( PASS( ret ) ); continue; } boost::system::error_code error_code; ip::address_v4 address_entry( ip::address_v4::from_string( addy, error_code ) ); if( error_code.value() ) { continue; } ip::address_v4 mask_entry( ip::address_v4::from_string( mask, error_code ) ); if( error_code.value() ) { continue; } ip::address_v4 host_client( ip::address_v4::from_string( _host_client, error_code ) ); if( error_code.value() ) { continue; } bool user_match = false; if( user == _user_name || user == "all" ) { user_match = true; } bool group_match = false; if( "all" == group ) { group_match = true; } else { for( size_t i = 0; i < group_list.size(); ++i ) { if( group == group_list[ i ] ) { group_match = true; } } // for i } if( group_match || user_match ) { // check if <client, group, clientIP> // match this entry of the control access file. if( ( ( host_client.to_ulong() ^ address_entry.to_ulong() ) & ~mask_entry.to_ulong() ) == 0 ) { return 0; } } } // for ae_idx return UNMATCHED_KEY_OR_INDEX; } // checkHostAccessControl