mirror of https://github.com/torvalds/linux.git
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>
This commit is contained in:
parent
36ae67b139
commit
bcc64b57b4
|
|
@ -342,6 +342,35 @@ static inline struct pt_table_p *pt_table_ptr(const struct pt_state *pts)
|
|||
return __va(pt_table_pa(pts));
|
||||
}
|
||||
|
||||
/**
|
||||
* pt_max_sw_bit() - Return the maximum software bit usable for any level and
|
||||
* entry
|
||||
* @common: Page table
|
||||
*
|
||||
* The swbit can be passed as bitnr to the other sw_bit functions.
|
||||
*/
|
||||
static inline unsigned int pt_max_sw_bit(struct pt_common *common);
|
||||
|
||||
/**
|
||||
* pt_test_sw_bit_acquire() - Read a software bit in an item
|
||||
* @pts: Entry to set
|
||||
*
|
||||
* Software bits are ignored by HW and can be used for any purpose by the
|
||||
* software. This does a test bit and acquire operation.
|
||||
*/
|
||||
static inline bool pt_test_sw_bit_acquire(struct pt_state *pts,
|
||||
unsigned int bitnr);
|
||||
|
||||
/**
|
||||
* pt_set_sw_bit_release() - Set a software bit in an item
|
||||
* @pts: Entry to set
|
||||
*
|
||||
* Software bits are ignored by HW and can be used for any purpose by the
|
||||
* software. This does a set bit and release operation.
|
||||
*/
|
||||
static inline void pt_set_sw_bit_release(struct pt_state *pts,
|
||||
unsigned int bitnr);
|
||||
|
||||
/**
|
||||
* pt_load_entry() - Read from the location pts points at into the pts
|
||||
* @pts: Table index to load
|
||||
|
|
|
|||
|
|
@ -202,6 +202,68 @@ static inline void pt_clear_entries(struct pt_state *pts,
|
|||
#define pt_clear_entries pt_clear_entries
|
||||
#endif
|
||||
|
||||
/* If not supplied then SW bits are not supported */
|
||||
#ifdef pt_sw_bit
|
||||
static inline bool pt_test_sw_bit_acquire(struct pt_state *pts,
|
||||
unsigned int bitnr)
|
||||
{
|
||||
/* Acquire, pairs with pt_set_sw_bit_release() */
|
||||
smp_mb();
|
||||
/* For a contiguous entry the sw bit is only stored in the first item. */
|
||||
return pts->entry & pt_sw_bit(bitnr);
|
||||
}
|
||||
#define pt_test_sw_bit_acquire pt_test_sw_bit_acquire
|
||||
|
||||
static inline void pt_set_sw_bit_release(struct pt_state *pts,
|
||||
unsigned int bitnr)
|
||||
{
|
||||
#if !IS_ENABLED(CONFIG_GENERIC_ATOMIC64)
|
||||
if (PT_ITEM_WORD_SIZE == sizeof(u64)) {
|
||||
u64 *entryp = pt_cur_table(pts, u64) + pts->index;
|
||||
u64 old_entry = pts->entry;
|
||||
u64 new_entry;
|
||||
|
||||
do {
|
||||
new_entry = old_entry | pt_sw_bit(bitnr);
|
||||
} while (!try_cmpxchg64_release(entryp, &old_entry, new_entry));
|
||||
pts->entry = new_entry;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (PT_ITEM_WORD_SIZE == sizeof(u32)) {
|
||||
u32 *entryp = pt_cur_table(pts, u32) + pts->index;
|
||||
u32 old_entry = pts->entry;
|
||||
u32 new_entry;
|
||||
|
||||
do {
|
||||
new_entry = old_entry | pt_sw_bit(bitnr);
|
||||
} while (!try_cmpxchg_release(entryp, &old_entry, new_entry));
|
||||
pts->entry = new_entry;
|
||||
} else
|
||||
BUILD_BUG();
|
||||
}
|
||||
#define pt_set_sw_bit_release pt_set_sw_bit_release
|
||||
#else
|
||||
static inline unsigned int pt_max_sw_bit(struct pt_common *common)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern void __pt_no_sw_bit(void);
|
||||
static inline bool pt_test_sw_bit_acquire(struct pt_state *pts,
|
||||
unsigned int bitnr)
|
||||
{
|
||||
__pt_no_sw_bit();
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void pt_set_sw_bit_release(struct pt_state *pts,
|
||||
unsigned int bitnr)
|
||||
{
|
||||
__pt_no_sw_bit();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Format can call in the pt_install_leaf_entry() to check the arguments are all
|
||||
* aligned correctly.
|
||||
|
|
|
|||
Loading…
Reference in New Issue