Combine 1 tablespoon garam masala, 1 teaspoon salt, ½ teaspoon cumin, coriander, and pepper in a 1-gallon zipper-lock bag. Toss the spices around to combine. Add lamb and shake to coat. Add yogurt, seal bag, and massage meat to coat. Transfer bag to refrigerator and marinate for 1 hour or up to overnight.
Heat oil in a 12-inch sauté pan over medium. Add onion and remaining 1 teaspoon salt and cook until softened and starting to brown, 8–10 minutes, stirring occasionally.
Reduce heat to medium-low and add garlic, serrano, and ginger; cook stirring frequently until onions are softened and golden brown, about 7 minutes.
Stir in remaining 1 tablespoon garam masala, remaining 1 teaspoon cumin, and ½ teaspoon cardamom; cook 1 minute.
Add tomatoes with juices, crushing them with your hands as you add them (or use your kitchen shears to cut them in the can). Bring sauce to a boil, reduce heat, and simmer, stirring frequently and scraping up browned bits from bottom of pan, until thickened and deepened in color, 15–20 minutes.
Add coconut milk and simmer until thickened, 5–7 minutes.
Meanwhile, heat oven to broil (high) with rack set in upper middle position Line a rimmed baking sheet with foil and set a wire rack inside sheet. Arrange lamb on rack in a single layer (don’t scrape marinade off). Broil lamb until starting to char, 10–12 minutes.
Add lamb to sauce, and simmer, stirring occasionally, until lamb is cooked through, about 8 minutes. Serve with rice, cilantro, and naan if desired.