|
@@ -2136,35 +2136,67 @@ static int hermon_map_vpm ( struct hermon *hermon,
|
2136
|
2136
|
const struct hermonprm_virtual_physical_mapping* ),
|
2137
|
2137
|
uint64_t va, physaddr_t pa, size_t len ) {
|
2138
|
2138
|
struct hermonprm_virtual_physical_mapping mapping;
|
|
2139
|
+ physaddr_t start;
|
|
2140
|
+ physaddr_t low;
|
|
2141
|
+ physaddr_t high;
|
|
2142
|
+ physaddr_t end;
|
|
2143
|
+ size_t size;
|
2139
|
2144
|
int rc;
|
2140
|
2145
|
|
|
2146
|
+ /* Sanity checks */
|
2141
|
2147
|
assert ( ( va & ( HERMON_PAGE_SIZE - 1 ) ) == 0 );
|
2142
|
2148
|
assert ( ( pa & ( HERMON_PAGE_SIZE - 1 ) ) == 0 );
|
2143
|
2149
|
assert ( ( len & ( HERMON_PAGE_SIZE - 1 ) ) == 0 );
|
2144
|
2150
|
|
|
2151
|
+ /* Calculate starting points */
|
|
2152
|
+ start = pa;
|
|
2153
|
+ end = ( start + len );
|
|
2154
|
+ size = ( 1UL << ( fls ( start ^ end ) - 1 ) );
|
|
2155
|
+ low = high = ( end & ~( size - 1 ) );
|
|
2156
|
+ assert ( start < low );
|
|
2157
|
+ assert ( high <= end );
|
|
2158
|
+
|
2145
|
2159
|
/* These mappings tend to generate huge volumes of
|
2146
|
2160
|
* uninteresting debug data, which basically makes it
|
2147
|
2161
|
* impossible to use debugging otherwise.
|
2148
|
2162
|
*/
|
2149
|
2163
|
DBG_DISABLE ( DBGLVL_LOG | DBGLVL_EXTRA );
|
2150
|
2164
|
|
2151
|
|
- while ( len ) {
|
|
2165
|
+ /* Map blocks in descending order of size */
|
|
2166
|
+ while ( size >= HERMON_PAGE_SIZE ) {
|
|
2167
|
+
|
|
2168
|
+ /* Find the next candidate block */
|
|
2169
|
+ if ( ( low - size ) >= start ) {
|
|
2170
|
+ low -= size;
|
|
2171
|
+ pa = low;
|
|
2172
|
+ } else if ( ( high + size ) <= end ) {
|
|
2173
|
+ pa = high;
|
|
2174
|
+ high += size;
|
|
2175
|
+ } else {
|
|
2176
|
+ size >>= 1;
|
|
2177
|
+ continue;
|
|
2178
|
+ }
|
|
2179
|
+ assert ( ( va & ( size - 1 ) ) == 0 );
|
|
2180
|
+ assert ( ( pa & ( size - 1 ) ) == 0 );
|
|
2181
|
+
|
|
2182
|
+ /* Map this block */
|
2152
|
2183
|
memset ( &mapping, 0, sizeof ( mapping ) );
|
2153
|
2184
|
MLX_FILL_1 ( &mapping, 0, va_h, ( va >> 32 ) );
|
2154
|
2185
|
MLX_FILL_1 ( &mapping, 1, va_l, ( va >> 12 ) );
|
2155
|
2186
|
MLX_FILL_2 ( &mapping, 3,
|
2156
|
|
- log2size, 0,
|
|
2187
|
+ log2size, ( ( fls ( size ) - 1 ) - 12 ),
|
2157
|
2188
|
pa_l, ( pa >> 12 ) );
|
2158
|
2189
|
if ( ( rc = map ( hermon, &mapping ) ) != 0 ) {
|
2159
|
2190
|
DBG_ENABLE ( DBGLVL_LOG | DBGLVL_EXTRA );
|
2160
|
|
- DBGC ( hermon, "Hermon %p could not map %llx => %lx: "
|
2161
|
|
- "%s\n", hermon, va, pa, strerror ( rc ) );
|
|
2191
|
+ DBGC ( hermon, "Hermon %p could not map %08llx+%zx to "
|
|
2192
|
+ "%08lx: %s\n",
|
|
2193
|
+ hermon, va, size, pa, strerror ( rc ) );
|
2162
|
2194
|
return rc;
|
2163
|
2195
|
}
|
2164
|
|
- pa += HERMON_PAGE_SIZE;
|
2165
|
|
- va += HERMON_PAGE_SIZE;
|
2166
|
|
- len -= HERMON_PAGE_SIZE;
|
|
2196
|
+ va += size;
|
2167
|
2197
|
}
|
|
2198
|
+ assert ( low == start );
|
|
2199
|
+ assert ( high == end );
|
2168
|
2200
|
|
2169
|
2201
|
DBG_ENABLE ( DBGLVL_LOG | DBGLVL_EXTRA );
|
2170
|
2202
|
return 0;
|