Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

iommupt: Add basic support for SW bits in the page table

SW bits can be placed on items, including table entries, single OA's and
individual items within a contiguous OA. They are guaranteed to be ignored
by the HW. The API is very basic since the only use case so far is a
single bit.

Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>

authored by

Jason Gunthorpe and committed by
Joerg Roedel
bcc64b57 36ae67b1

+91
+29
drivers/iommu/generic_pt/pt_common.h
··· 343 343 } 344 344 345 345 /** 346 + * pt_max_sw_bit() - Return the maximum software bit usable for any level and 347 + * entry 348 + * @common: Page table 349 + * 350 + * The swbit can be passed as bitnr to the other sw_bit functions. 351 + */ 352 + static inline unsigned int pt_max_sw_bit(struct pt_common *common); 353 + 354 + /** 355 + * pt_test_sw_bit_acquire() - Read a software bit in an item 356 + * @pts: Entry to set 357 + * 358 + * Software bits are ignored by HW and can be used for any purpose by the 359 + * software. This does a test bit and acquire operation. 360 + */ 361 + static inline bool pt_test_sw_bit_acquire(struct pt_state *pts, 362 + unsigned int bitnr); 363 + 364 + /** 365 + * pt_set_sw_bit_release() - Set a software bit in an item 366 + * @pts: Entry to set 367 + * 368 + * Software bits are ignored by HW and can be used for any purpose by the 369 + * software. This does a set bit and release operation. 370 + */ 371 + static inline void pt_set_sw_bit_release(struct pt_state *pts, 372 + unsigned int bitnr); 373 + 374 + /** 346 375 * pt_load_entry() - Read from the location pts points at into the pts 347 376 * @pts: Table index to load 348 377 *
+62
drivers/iommu/generic_pt/pt_fmt_defaults.h
··· 202 202 #define pt_clear_entries pt_clear_entries 203 203 #endif 204 204 205 + /* If not supplied then SW bits are not supported */ 206 + #ifdef pt_sw_bit 207 + static inline bool pt_test_sw_bit_acquire(struct pt_state *pts, 208 + unsigned int bitnr) 209 + { 210 + /* Acquire, pairs with pt_set_sw_bit_release() */ 211 + smp_mb(); 212 + /* For a contiguous entry the sw bit is only stored in the first item. */ 213 + return pts->entry & pt_sw_bit(bitnr); 214 + } 215 + #define pt_test_sw_bit_acquire pt_test_sw_bit_acquire 216 + 217 + static inline void pt_set_sw_bit_release(struct pt_state *pts, 218 + unsigned int bitnr) 219 + { 220 + #if !IS_ENABLED(CONFIG_GENERIC_ATOMIC64) 221 + if (PT_ITEM_WORD_SIZE == sizeof(u64)) { 222 + u64 *entryp = pt_cur_table(pts, u64) + pts->index; 223 + u64 old_entry = pts->entry; 224 + u64 new_entry; 225 + 226 + do { 227 + new_entry = old_entry | pt_sw_bit(bitnr); 228 + } while (!try_cmpxchg64_release(entryp, &old_entry, new_entry)); 229 + pts->entry = new_entry; 230 + return; 231 + } 232 + #endif 233 + if (PT_ITEM_WORD_SIZE == sizeof(u32)) { 234 + u32 *entryp = pt_cur_table(pts, u32) + pts->index; 235 + u32 old_entry = pts->entry; 236 + u32 new_entry; 237 + 238 + do { 239 + new_entry = old_entry | pt_sw_bit(bitnr); 240 + } while (!try_cmpxchg_release(entryp, &old_entry, new_entry)); 241 + pts->entry = new_entry; 242 + } else 243 + BUILD_BUG(); 244 + } 245 + #define pt_set_sw_bit_release pt_set_sw_bit_release 246 + #else 247 + static inline unsigned int pt_max_sw_bit(struct pt_common *common) 248 + { 249 + return 0; 250 + } 251 + 252 + extern void __pt_no_sw_bit(void); 253 + static inline bool pt_test_sw_bit_acquire(struct pt_state *pts, 254 + unsigned int bitnr) 255 + { 256 + __pt_no_sw_bit(); 257 + return false; 258 + } 259 + 260 + static inline void pt_set_sw_bit_release(struct pt_state *pts, 261 + unsigned int bitnr) 262 + { 263 + __pt_no_sw_bit(); 264 + } 265 + #endif 266 + 205 267 /* 206 268 * Format can call in the pt_install_leaf_entry() to check the arguments are all 207 269 * aligned correctly.